home *** CD-ROM | disk | FTP | other *** search
/ Compendium Deluxe 2 / LSD and 17bit Compendium Deluxe - Volume II.iso / a / prog / misc / date.lha / Date / M2 / txt / Date.mod < prev    next >
Text File  |  1994-11-30  |  105KB  |  4,427 lines

  1.  IMPLEMENTATION MODULE Date; (* Copyright 1994 Kai Hofmann *)
  2.  
  3. (*
  4. ******* Date/--history-- ****************************************************
  5. *
  6. *   NAME
  7. *    history -- This is the development history of the Date module
  8. *
  9. *   VERSION
  10. *    $VER: Date 33.089 (30.11.1994)
  11. *
  12. *   HISTORY
  13. *    16.01.1994 -    Procedures: JulianLeapYear, GregorianLeapYear &
  14. *            HeisLeapYear initiated.
  15. *    22.01.1994 -    Procedures: JulianMonthDays, GregorianMonthDays,
  16. *            HeisMonthDays, JulianYearDays, GregorianYearDays,
  17. *            HeisYearDays, JulianDayDiff, GregorianDayDiff,
  18. *            HeisDayDiff, JulianDaySmaller, GregorianDaySmaller,
  19. *            HeisDaySmaller, JulianWeekday, GregorianWeekday,
  20. *            HeisWeekday, JulianDaysBeforeWeekday,
  21. *            GregorianDaysBeforeWeekday, HeisDaysBeforeWeekday,
  22. *            JulianDaysAfterWeekday, GregorianDaysAfterWeekday,
  23. *            HeisDaysAfterWeekday JulianDiffDate, FreeDate
  24. *            initiated.
  25. *            Types: Weekdays, Date, DatePtr initiated.
  26. *            Vars of Gregorian reform initiated
  27. *            (for changing to different countries)
  28. *    23.01.1994 -    Procedures: JulianDiffDate finished,
  29. *            GregorianDiffDate, HeisDiffDate, JYearToScaliger,
  30. *            GYearToScaliger, HYearToScaliger, ScaligerYearToJ,
  31. *            ScaligerYearToG, ScaligerYearToH, JSYearToJD,
  32. *            GSYearToJD, HSYearToJD, JDtoMJD, MJDtoJD, JulianToJD,
  33. *            GregorianToJD, HeisToJD, TimeToJD, JDToTime, FreeTime
  34. *            initiated.
  35. *            Types: Time, TimePtr initiated.
  36. *    28.01.1994 -    Procedures: GregorianMoonAge, MoonMonthAge,
  37. *            GregorianEaster initiated.
  38. *    30.01.1994 -    Procedures: JulianDiffDate, GregorianDiffDate,
  39. *            HeisDiffDate, JDtoTime, GregorianEaster edited
  40. *            (changing return value from ptr to VAL variables).
  41. *            Procedures: FreeDate, FreeTime deleted.
  42. *            Types: Date, DatePtr, Time, TimePtr deleted (not
  43. *            longer needed, because of the procedure changes).
  44. *            Procedures: GregorianMoonAge, GregorianEaster changed
  45. *            year parameter from CARDINAL to INTEGER (this is more
  46. *            consistent to the rest of the library).
  47. *            Bugs removed: GregorianWeekday, HeisWeekday
  48. *            (before removing, the weekday for leapyears was
  49. *            wrong)
  50. *            Procedure: GregorianEaster finished.
  51. *    30.01.1994 -    Ported to Oberon-2
  52. *    31.01.1994 -    Compiled with Oberon-2 V3.11
  53. *    12.02.1994 -    Procedures: TimeZoneFactor, LMT, TimeToSec, SecToTime
  54. *            initiated.
  55. *            Version-String installed :)
  56. *    12.02.1994 -    Starting translation to SAS C 6.51
  57. *            Date.h translated
  58. *    13.02.1994 -    Continuation of C translation
  59. *    17.02.1994 -    New Oberon-2 Port, because yesterday Daniel Armor
  60. *            gives me a small hint about the SHORT command
  61. *            (I did not know about this!)
  62. *    17.02.1994 -    Small bug in Autodocs removed
  63. *            making this text as Date/--history-- autodoc
  64. *    17.02.1994 -    Continuation of C translation
  65. *    18.02.1994 -    Finished with C translation
  66. *    19.02.1994 -    C bugs removed (thanx to SAS for helping a C Lamer
  67. *            like me!), some optimizations done too.
  68. *    19.02.1994 -    Oberon-2 version compiled with V40.17 includes
  69. *    21.02.1994 -    Starting to write Modula-II testmodule
  70. *            Vars for the begining of Heis calculation initiated.
  71. *            Fixed small bugs in GregorianWeekday, HeisWeekday,
  72. *            TimeToSec, SecToTime
  73. *            Return-value of LMT changed to LONGINT!
  74. *            Converting testmodule to Oberon-2
  75. *    22.02.1994 -    Converting testmodule to C
  76. *    23.02.1994 -    I noticed, that I forgot the 3 functions
  77. *            JulianWeek, GregorianWeek, HeisWeek
  78. *    24.02.1994 -    Initiated the 3 forgotten functions
  79. *    26.02.1994 -    Initiating new GregorianEastern with Gauß-algorithms
  80. *            but ONLY for 1900-2099!
  81. *    27.02.1994 -    Bug fixed in JulianWeekday
  82. *            Bugs fixed in JulianDayDiff, GregorianDayDiff,
  83. *            HeisDayDiff
  84. *            JulianDayGreater, GregorianDayGreater,
  85. *            HeisDayGreater Initiated.
  86. *    02.03.1994 -    Small bug fixed in HeisdayDiff
  87. *            Bugs from 27.02. fixed in Modula-II and Oberon-2
  88. *            versions
  89. *            I found the way to extend Gregorian Easter!
  90. *            Small bug fixed in JulianWeek, GregorianWeek,
  91. *            HeisWeek (~(M2) is not !(C))
  92. *    05.03.1994 -    Some internal bugs removed
  93. *            New internal procedures GregorianSB,
  94. *            GregorianJHSB, GregorianJHStartSB!
  95. *            Extending GregorianEaster :)
  96. *    11.03.1994 -    Things from 05.03. done in Modula-II and Oberon
  97. *    12.03.1994 -    If __SASC is defined autoinitalization instead of
  98. *            _DateInit will be used!
  99. *    13.03.1994 -    After studying the SAS C Manual again I decided to
  100. *            check for __SASC_650 instead of __SASC because of
  101. *            the available priorities!
  102. *            Setting the priority of _DateInit for
  103. *            autoinitalization to 600!
  104. *    15.03.1994 -    Making Date as library
  105. *    16.03.1994 -    Some work on the Autodocs was done
  106. *            Eleminating OldGregorianEaster by comments
  107. *            (ANSI: STOP bad standards like that there are NO
  108. *             nested comments possible in C!!!)
  109. *    19.03.1994 -    Some work on the Autodocs was done in the M2 Code
  110. *    20.03.1994 -    Some work on the Autodocs was done in the Oberon Code
  111. *    22.03.1994 -    In JDtoMJD, MJD to JD an L was added to the constant
  112. *            In GregorianWeekday(), HeisWeekday(),
  113. *            JulianDiffDate(), GregorianDiffDate(),
  114. *            HeisDiffDate(), JDToTime() I have inserted
  115. *            conversions (found with Borland C++ 4.0)
  116. *    24.03.1994 -    Making SunOS4.1.3, SunOS5.3(Solaris2.3) &
  117. *            RS6000 AIX3.2.? binaries with gcc
  118. *            Eliminating nested commends by inserting a space
  119. *            between / and * (I hate this ANSI C standard
  120. *            feature for commends :(
  121. *    27.03.1994 -    Adding library register assignments to the autodocs
  122. *    03.04.1994 -    Small fixes for the SAS C++ Compiler
  123. *            Small bug fixed in the M2 version of GregorianEaster
  124. *    04.04.1994 -    Adding some 'static' keywords
  125. *    10.04.1994 -    Changing from Shareware to Gift Ware ;-)
  126. *    02.08.1994 -    Small fixes in the Autodocs (thanks to Rita Reichl
  127. *            for correcting my bad english ;-)
  128. *    11.08.1994 -    Again small fixes in the Autodocs!
  129. *    13.11.1994 -    Small fix in JulianWeek(),GregorianWeek(),HeisWeek().
  130. *            Thanks to Jim Rickman for reporting the bug!
  131. *            Small changes in the Autodocs!
  132. *    30.11.1994 -    Fix the bug from 13.11. in M2 and Oberon code.
  133. *
  134. *****************************************************************************
  135. *
  136. *
  137. *)
  138.  
  139. (*
  140. ******* Date/--background-- *************************************************
  141. *
  142. *   NAME
  143. *    Date -- This module was designed to help calc. calendar dates (V33)
  144. *
  145. *   FUNCTION
  146. *    I know about the date routines in the Amiga-OS(TM), but I decided
  147. *    not to use them, because of their limited functionalities and of
  148. *    the portability of this module!
  149. *
  150. *   NOTES
  151. *    A tropical year is 365.2422 days! / 365d, 5h, 48min, 46sec
  152. *    A moon month is 29.53059 days! / 29d, 12h, 44min, 2.9 sec
  153. *    A moon phase is 7.38265 days!
  154. *
  155. *    (German) Books which helped me creating this library:
  156. *        Kleine Naturwissenschaftliche Bibliothek, Band 23
  157. *        Ewige Kalender
  158. *        A.W. Butkewitsch & M.S. Selikson
  159. *        5. Auflage
  160. *        Teubner, Leipzig 1974
  161. *        ISBN 3-322-00393-0
  162. *
  163. *        Tag und Woche, Monat und Jahr: eine Kulturgeschichte des
  164. *        Kalenders
  165. *        Rudolf Wendorff
  166. *        Westdeutscher, Opladen 1993
  167. *        ISBN 3-531-12417-X
  168. *
  169. *        Kalender und Chronologie: Bekanntes & Unbekanntes aus der
  170. *        Kalenderwissenschaft
  171. *        Heinz Zemanek
  172. *        4. Auflage
  173. *        Oldenbourg, München 1987
  174. *        ISBN 3-486-20447-5
  175. *
  176. *        Meyers Handbuch
  177. *        über das Weltall
  178. *        Karl Schaifers & Gerhard Traving
  179. *        5. Auflage
  180. *        Bibliographisches Institut Mannheim 1973
  181. *        ISBN 3-411-00940-3
  182. *
  183. *        Meyers Handbuch
  184. *        über das Weltall
  185. *        Karl Schaifers & Gerhard Traving
  186. *        5. Auflage
  187. *        Bibliographisches Institut Mannheim 1973
  188. *        ISBN 3-411-00940-3
  189. *
  190. *    (English) Books which helped me creating this library:
  191. *        Mathematical Astronomy with a Pocket Calculator
  192. *        Aubrey Jones Fras
  193. *        unknown(first) Edition
  194. *        David & Charles Newton Abbot, London 1978
  195. *        ISBN 0-7153-7675-6
  196. *
  197. *   COPYRIGHT
  198. *    This module is Copyright 1994 by Kai Hofmann - all rights reserved!
  199. *    For private use, Public Domain, Gift Ware, Freeware and Shareware
  200. *    you could use this module under following conditions:
  201. *    - You send me a little gift (money is very welcome :)
  202. *        For Bank Account see below - but *ONLY* send in DM
  203. *        to this Bank Account!!!
  204. *      Other nice gifts: all Amiga hardware, and I am searching for a
  205. *      good old 1541 (C64 floppy)
  206. *    - You include a notice in your product, that you use this library
  207. *      and that it is Copyright by Kai Hofmann!
  208. *    If you want to redistribute this library read the following points:
  209. *    - Redistribution warranty is given to:
  210. *        Fred Fish for his great Amiga-Software-Library
  211. *        The German SAAR AG PD-Library
  212. *        The German AMOK PD-Library
  213. *        All public accessible INTERNET servers and PHONE boxes!
  214. *        All other who NOT take more than DM 5.- for one disk
  215. *        ALL other who NOT take more than DM 50.- for one CD
  216. *    For commercial use send me DM 200.-
  217. *    But if you are Apple or Microsoft you have to send (20000.- US$)
  218. *
  219. *   DISCLAIMER
  220. *
  221. *      THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
  222. *   APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
  223. *   HOLDER AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
  224. *   OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
  225. *   THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  226. *   PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
  227. *   PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE
  228. *   COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
  229. *
  230. *      IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
  231. *   WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY REDISTRIBUTE THE
  232. *   PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
  233. *   GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
  234. *   USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS
  235. *   OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR
  236. *   THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
  237. *   PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
  238. *   POSSIBILITY OF SUCH DAMAGES.
  239. *
  240. *   ADDITIONAL INFORMATIONS
  241. *    I have tried to make portable/usefull and I hope bugfree software
  242. *    for eternity - but this seems to be impossible (sorry!) :)
  243. *    So I hope you will pay a fee for this.
  244. *
  245. *   AUTHOR
  246. *    Kai Hofmann
  247. *    Arberger Heerstraße 92
  248. *    28307 Bremen
  249. *    Germany
  250. *    EMail: i07m@alf.zfn.uni-bremen.de
  251. *    (no phone - I hate it!)
  252. *
  253. *    Bank account : 1203 7503
  254. *    Account owner: Kai Hofmann
  255. *    Bank code    : 290 501 01
  256. *    Bank name    : Sparkasse in Bremen
  257. *    Bank address : 28307 Bremen / Germany
  258. *
  259. *   THANX
  260. *    Thanx are going to the following people:
  261. *    Danial Armor        - For his hint about the Oberon-2 SHORT
  262. *                  command
  263. *    Heinz Zemanek        - For his great book
  264. *    Christian Schaefer    - For spending time on this lib with his
  265. *                  Borland C++ 4.0 compiler
  266. *    Rita Reichl        - For correcting my bad english ;-)
  267. *    Jim Rickman        - For reporting a bug
  268. *
  269. *****************************************************************************
  270. *
  271. *
  272. *)
  273.  (*
  274.  (*$ StackChk       := FALSE *)
  275.  (*$ RangeChk       := FALSE *)
  276.  (*$ OverflowChk    := FALSE *)
  277.  (*$ NilChk         := FALSE *)
  278.  (*$ CaseChk        := FALSE *)
  279.  (*$ ReturnChk      := FALSE *)
  280.  (*$ LargeVars      := FALSE *)
  281.  (*$ EntryClear     := TRUE  *)
  282.  (*$ Volatile       := TRUE  *)
  283.  (*$ StackParms     := TRUE  *)
  284.  (*$ CStrings       := TRUE  *)
  285.  *)
  286.  
  287.  
  288.  VAR
  289.     BeforeGregorianDay, BeforeGregorianMonth,
  290.     AfterGregorianDay, AfterGregorianMonth,
  291.     StartHeisDay, StartHeisMonth            : SHORTCARD;
  292.     BeforeGregorianYear, AfterGregorianYear,
  293.     StartHeisYear                    : INTEGER;
  294.  
  295.  (* ----------------------------------------------------------------------- *)
  296.  
  297.  PROCEDURE JulianLeapYear(year : INTEGER) : BOOLEAN;
  298.  
  299. (*
  300. ******* Date/JulianLeapYear *************************************************
  301. *
  302. *   NAME
  303. *    JulianLeapYear -- Checks if a year is a leap year. (V33)
  304. *
  305. *   SYNOPSIS
  306. *    leapyear := JulianLeapYear(year);
  307. *
  308. *    PROCEDURE JulianLeapYear(year : INTEGER) : BOOLEAN;
  309. *
  310. *   FUNCTION
  311. *    JulianLeapYear checks if a year is a leap year in the julian calendar
  312. *    For years after Chr. it checks if the year is devideable by 4.
  313. *    For years before Chr. a leap year must have a modulo 4 value of 1
  314. *
  315. *   INPUTS
  316. *    year - The year which should be checked (from -32768 to 32767)
  317. *        I think only values from -7 to 1582 are valid, because of
  318. *        the variant that was done on -8 by Augustus and other things!
  319. *
  320. *   RESULT
  321. *    leapyear - TRUE if the year is a leap year, otherwise false.
  322. *
  323. *   EXAMPLE
  324. *    ...
  325. *    IF JulianLeapYear(1994) THEN
  326. *      WriteString("leap year!");
  327. *    ELSE
  328. *      WriteString("no leap year!");
  329. *    END;
  330. *    WriteLn;
  331. *    ...
  332. *
  333. *   NOTES
  334. *    A year is 365.25 days long!
  335. *    Use this function only for values from -7 to 1582!
  336. *
  337. *   BUGS
  338. *    No known bugs.
  339. *
  340. *   SEE ALSO
  341. *    GregorianLeapYear(),HeisLeapYear()
  342. *
  343. *****************************************************************************
  344. *
  345. *
  346. *)
  347.  
  348.  BEGIN
  349.    IF year <= 0 THEN
  350.      RETURN(ABS(year) MOD 4 = 1);
  351.    ELSE    (* year > 0 *)
  352.      RETURN(year MOD 4 = 0);
  353.    END;
  354.  END JulianLeapYear;
  355.  
  356.  
  357.  PROCEDURE GregorianLeapYear(year : INTEGER) : BOOLEAN;
  358.  
  359. (*
  360. ******* Date/GregorianLeapYear **********************************************
  361. *
  362. *   NAME
  363. *    GregorianLeapYear -- Checks if a year is a leap year. (V33)
  364. *
  365. *   SYNOPSIS
  366. *    leapyear := GregorianLeapYear(year);
  367. *
  368. *    PROCEDURE GregorianLeapYear(year : INTEGER) : BOOLEAN;
  369. *
  370. *   FUNCTION
  371. *    GregorianLeapYear checks if a year is a leap year.
  372. *    For years after 1582 all years devideable by 4 are leap years,
  373. *    without years devideable by 100, but years devideable by 400
  374. *    are leap years again!
  375. *    For years before 1582 see JulianLeapYear().
  376. *
  377. *   INPUTS
  378. *    year - The year which should be checked (from -32768 to 32767)
  379. *        I think only values from -7 to 3200 are valid, because of
  380. *        the variant that was done on -8 by Augustus and other things!
  381. *
  382. *   RESULT
  383. *    leapyear - TRUE if the year is a leap year, otherwise false.
  384. *
  385. *   EXAMPLE
  386. *    ...
  387. *    IF GregorianLeapYear(1994) THEN
  388. *      WriteString("leap year!");
  389. *    ELSE
  390. *      WriteString("no leap year!");
  391. *    END;
  392. *    WriteLn;
  393. *    ...
  394. *
  395. *   NOTES
  396. *    A year is 365.2425 days long!
  397. *    Use this function only for values from -7 to 3199
  398. *
  399. *   BUGS
  400. *    No known bugs.
  401. *
  402. *   SEE ALSO
  403. *    JulianLeapYear(),HeisLeapYear()
  404. *
  405. *****************************************************************************
  406. *
  407. *
  408. *)
  409.  
  410.  BEGIN
  411.    IF year < BeforeGregorianYear THEN    (* Year of the Gregorian reform *)
  412.      RETURN(JulianLeapYear(year));
  413.    ELSE    (* AfterGregorianYear reform *)
  414.      RETURN((year MOD 4 = 0) AND ((year MOD 100 > 0) OR (year MOD 400 = 0)));
  415.    END;
  416.  END GregorianLeapYear;
  417.  
  418.  
  419.  PROCEDURE HeisLeapYear(year : INTEGER) : BOOLEAN;
  420.  
  421. (*
  422. ******* Date/HeisLeapYear ***************************************************
  423. *
  424. *   NAME
  425. *    HeisLeapYear -- Checks if a year is a leap year. (V33)
  426. *
  427. *   SYNOPSIS
  428. *    leapyear := HeisLeapYear(year);
  429. *
  430. *    PROCEDURE HeisLeapYear(year : INTEGER) : BOOLEAN;
  431. *
  432. *   FUNCTION
  433. *    HeisLeapYear checks if a year is a leap year.
  434. *    For years after 1582 see GregorianLeapYear(),
  435. *    The correction from N. Heis says, that all years devideable by
  436. *    3200 are no longer leap years!
  437. *    For years before 1582 see JulianLeapYear
  438. *
  439. *   INPUTS
  440. *    year - The year which should be checked (from -32768 to 32767)
  441. *        I think only values from -7 to 8000 are valid, because of
  442. *        the variant that was done on -8 by Augustus and other things!
  443. *
  444. *   RESULT
  445. *    leapyear - TRUE if the year is a leap year, otherwise false.
  446. *
  447. *   EXAMPLE
  448. *    ...
  449. *    IF HeisLeapYear(1994) THEN
  450. *      WriteString("leap year!");
  451. *    ELSE
  452. *      WriteString("no leap year!");
  453. *    END;
  454. *    WriteLn;
  455. *    ...
  456. *
  457. *   NOTES
  458. *    A year is now 365.2421875 days!
  459. *    Use this function only for values from -7 to 8000!
  460. *
  461. *   BUGS
  462. *    No known bugs.
  463. *
  464. *   SEE ALSO
  465. *    JulianLeapYear(),GregorianLeapYear()
  466. *
  467. *****************************************************************************
  468. *
  469. *
  470. *)
  471.  
  472.  BEGIN
  473.    IF year < BeforeGregorianYear THEN    (* Year of the Gregorian reform *)
  474.      RETURN(JulianLeapYear(year));
  475.    ELSE (* year >= AfterGregorianYear *)
  476.      IF year MOD 3200 = 0 THEN    (* Correction from N. Heis *)
  477.        RETURN(FALSE);        (* (no leap year all 3200 years) *)
  478.      ELSE
  479.        RETURN(GregorianLeapYear(year));
  480.      END;
  481.    END;
  482.  END HeisLeapYear;
  483.  
  484.  (* ----------------------------------------------------------------------- *)
  485.  
  486.  PROCEDURE JulianMonthDays(month : SHORTCARD; year : INTEGER) : SHORTCARD;
  487.  
  488. (*
  489. ******* Date/JulianMonthDays ************************************************
  490. *
  491. *   NAME
  492. *    JulianMonthDays -- Gives back the number of days of a month. (V33)
  493. *
  494. *   SYNOPSIS
  495. *    days := JulianMonthDays(month,year);
  496. *
  497. *    PROCEDURE JulianMonthDays(month : SHORTCARD;
  498. *        year : INTEGER) : SHORTCARD;
  499. *
  500. *   FUNCTION
  501. *    JulianMonthDays gives you back the number of days a month in
  502. *    a specified year has.
  503. *
  504. *   INPUTS
  505. *    month - The month from wich you want to get the number of days.
  506. *    year  - The year in which the month is.
  507. *
  508. *   RESULT
  509. *    days - The number of days the month uses, or 0 if you use
  510. *        a wrong month.
  511. *
  512. *   EXAMPLE
  513. *    ...
  514. *    days := JulianMonthDays(1,1994);
  515. *    WriteString("Days of January 1994 : ");
  516. *    WriteCard(days,2); WriteLn;
  517. *    ...
  518. *
  519. *   NOTES
  520. *    It is better only to use this function for years from -7 to 09.1582!
  521. *
  522. *   BUGS
  523. *    No known bugs.
  524. *
  525. *   SEE ALSO
  526. *    JulianLeapYear(),GregorianMonthDays(),HeisMonthDays()
  527. *
  528. *****************************************************************************
  529. *
  530. *
  531. *)
  532.  
  533.  BEGIN
  534.    IF month IN {1,3,5,7,8,10,12} THEN
  535.      RETURN(31);
  536.    ELSIF month IN {4,6,9,11} THEN
  537.      RETURN(30);
  538.    ELSIF (month = 2) AND JulianLeapYear(year) THEN
  539.      RETURN(29);
  540.    ELSIF (month = 2) AND (NOT JulianLeapYear(year)) THEN
  541.      RETURN(28);
  542.    ELSE (* Error - wrong month *)
  543.      RETURN(0);
  544.    END;
  545.  END JulianMonthDays;
  546.  
  547.  
  548.  PROCEDURE GregorianMonthDays(month : SHORTCARD; year : INTEGER) : SHORTCARD;
  549.  
  550. (*
  551. ******* Date/GregorianMonthDays *********************************************
  552. *
  553. *   NAME
  554. *    GregorianMonthDays -- Gives back the number of days of a month. (V33)
  555. *
  556. *   SYNOPSIS
  557. *    days := GregorianMonthDays(month,year);
  558. *
  559. *    PROCEDURE GregorianMonthDays(month : SHORTCARD;
  560. *        year : INTEGER) : SHORTCARD;
  561. *
  562. *   FUNCTION
  563. *    GregorianMonthDays gives you back the number of days a month in
  564. *    a specified year has.
  565. *    For the year 1582 and the month 10 there are only 21 days,
  566. *    because of the Gregorian-reform 10 days are delete from
  567. *    the month (for more - look out for books about this!)
  568. *
  569. *   INPUTS
  570. *    month - The month from wich you want to get the number of days.
  571. *    year  - The year in which the month is.
  572. *
  573. *   RESULT
  574. *    days - The number of days the month uses, or 0 if you use
  575. *        a wrong month.
  576. *
  577. *   EXAMPLE
  578. *    ...
  579. *    days := GregorianMonthDays(1,1994);
  580. *    WriteString("Days of January 1994 : ");
  581. *    WriteCard(days,2); WriteLn;
  582. *    ...
  583. *
  584. *   NOTES
  585. *    Use this function only for years from -7 to 3199!
  586. *
  587. *   BUGS
  588. *    If the reform in a country is not in the same month an error will
  589. *    occur!
  590. *
  591. *   SEE ALSO
  592. *    GregorianLeapYear(),JulianMonthDays(),HeisMonthDays()
  593. *
  594. *****************************************************************************
  595. *
  596. *
  597. *)
  598.  
  599.  BEGIN
  600.    IF (year = AfterGregorianYear) AND (month = AfterGregorianMonth) THEN
  601.      (* 10 days canceled by Gregor XIII
  602.         in countries who chnaged later are more days *)
  603.      RETURN(31-((AfterGregorianDay-BeforeGregorianDay)-1));
  604.    ELSIF (month = 2) AND GregorianLeapYear(year) THEN
  605.      RETURN(29);
  606.    ELSIF (month = 2) AND (NOT GregorianLeapYear(year)) THEN
  607.      RETURN(28);
  608.    ELSE (* use Julian function for other calcs. *)
  609.      RETURN(JulianMonthDays(month,year));
  610.    END;
  611.  END GregorianMonthDays;
  612.  
  613.  
  614.  PROCEDURE HeisMonthDays(month : SHORTCARD; year : INTEGER) : SHORTCARD;
  615.  
  616. (*
  617. ******* Date/HeisMonthDays **************************************************
  618. *
  619. *   NAME
  620. *    HeisMonthDays -- Gives back the number of days of a month. (V33)
  621. *
  622. *   SYNOPSIS
  623. *    days := HeisMonthDays(month,year);
  624. *
  625. *    PROCEDURE HeisMonthDays(month : SHORTCARD;
  626. *        year : INTEGER) : SHORTCARD;
  627. *
  628. *   FUNCTION
  629. *    HeisMonthDays gives you back the number of days a month in
  630. *    a specified year has.
  631. *    For the year 1582 and the month 10 there are only 21 days,
  632. *    because of the Gregorian-reform 10 days are delete from
  633. *    the month (for more - look out for books about this!)
  634. *
  635. *   INPUTS
  636. *    month - The month from wich you want to get the number of days.
  637. *    year  - The year in which the month is.
  638. *
  639. *   RESULT
  640. *    days - The number of days the month uses, or 0 if you use
  641. *        a wrong month.
  642. *
  643. *   EXAMPLE
  644. *    ...
  645. *    days := HeisMonthDays(1,1994);
  646. *    WriteString("Days of January 1994 : ");
  647. *    WriteCard(days,2); WriteLn;
  648. *    ...
  649. *
  650. *   NOTES
  651. *    Use this function only for years from -7 to 8000!
  652. *
  653. *   BUGS
  654. *    See GregorianMonthDays!
  655. *
  656. *   SEE ALSO
  657. *    HeisLeapYear(),JulianMonthDays(),GregorianMonthDays()
  658. *
  659. *****************************************************************************
  660. *
  661. *
  662. *)
  663.  
  664.  BEGIN
  665.    IF (month = 2) AND HeisLeapYear(year) THEN
  666.      RETURN(29);
  667.    ELSIF (month = 2) AND (NOT HeisLeapYear(year)) THEN
  668.      RETURN(28);
  669.    ELSE (* use Gregorian function for other calcs *)
  670.      RETURN(GregorianMonthDays(month,year));
  671.    END;
  672.  END HeisMonthDays;
  673.  
  674.  (* ----------------------------------------------------------------------- *)
  675.  
  676.  PROCEDURE JulianYearDays(year : INTEGER) : CARDINAL;
  677.  
  678. (*
  679. ******* Date/JulianYearDays *************************************************
  680. *
  681. *   NAME
  682. *    JulianYearDays -- Gives back the number of days in a year. (V33)
  683. *
  684. *   SYNOPSIS
  685. *    days := JulianYearDays(year);
  686. *
  687. *    PROCEDURE JulianYearDays(year : INTEGER) : CARDINAL;
  688. *
  689. *   FUNCTION
  690. *    JulianYearDays gives you back the number of days in
  691. *    a specified year.
  692. *
  693. *   INPUTS
  694. *    year  - The year in which to count the days.
  695. *
  696. *   RESULT
  697. *    days - The number of days the year uses.
  698. *
  699. *   EXAMPLE
  700. *    ...
  701. *    days := JulianYearDays(1994);
  702. *    WriteString("Days of 1994 : ");
  703. *    WriteCard(days,3); WriteLn;
  704. *    ...
  705. *
  706. *   NOTES
  707. *    It is better only to use this function for years from -7 to 1581!
  708. *
  709. *   BUGS
  710. *    No known bugs.
  711. *
  712. *   SEE ALSO
  713. *    JulianMonthDays(),GregorianYearDays(),HeisYearDays()
  714. *
  715. *****************************************************************************
  716. *
  717. *
  718. *)
  719.  
  720.  VAR
  721.     month    : SHORTCARD;
  722.     days    : CARDINAL;
  723.  
  724.  BEGIN
  725.    days := 0;
  726.    FOR month := 1 TO 12 DO (* add the days of all 12 month *)
  727.      days := days + JulianMonthDays(month,year);
  728.    END;
  729.    RETURN(days);
  730.  END JulianYearDays;
  731.  
  732.  
  733.  PROCEDURE GregorianYearDays(year : INTEGER) : CARDINAL;
  734.  
  735. (*
  736. ******* Date/GregorianYearDays **********************************************
  737. *
  738. *   NAME
  739. *    GregorianYearDays -- Gives back the number of days in a year. (V33)
  740. *
  741. *   SYNOPSIS
  742. *    days := GregorianYearDays(year);
  743. *
  744. *    PROCEDURE GregorianYearDays(year : INTEGER) : CARDINAL;
  745. *
  746. *   FUNCTION
  747. *    GregorianYearDays gives you back the number of days in
  748. *    a specified year.
  749. *
  750. *   INPUTS
  751. *    year  - The year in which to count the days.
  752. *
  753. *   RESULT
  754. *    days - The number of days the year uses.
  755. *
  756. *   EXAMPLE
  757. *    ...
  758. *    days := GregorianYearDays(1994);
  759. *    WriteString("Days of 1994 : ");
  760. *    WriteCard(days,3); WriteLn;
  761. *    ...
  762. *
  763. *   NOTES
  764. *    It is better only to use this function for years from -7 to 3199!
  765. *
  766. *   BUGS
  767. *    No known bugs.
  768. *
  769. *   SEE ALSO
  770. *    GregorianMonthDays(),JulianYearDays(),HeisYearDays()
  771. *
  772. *****************************************************************************
  773. *
  774. *
  775. *)
  776.  
  777.  VAR
  778.     month    : SHORTCARD;
  779.     days    : CARDINAL;
  780.  
  781.  BEGIN
  782.    days := 0;
  783.    FOR month := 1 TO 12 DO (* add the days of all 12 month *)
  784.      days := days + GregorianMonthDays(month,year);
  785.    END;
  786.    RETURN(days);
  787.  END GregorianYearDays;
  788.  
  789.  
  790.  PROCEDURE HeisYearDays(year : INTEGER) : CARDINAL;
  791.  
  792. (*
  793. ******* Date/HeisYearDays ***************************************************
  794. *
  795. *   NAME
  796. *    HeisYearDays -- Gives back the number of days in a year. (V33)
  797. *
  798. *   SYNOPSIS
  799. *    days := HeisYearDays(year);
  800. *
  801. *    PROCEDURE HeisYearDays(year : INTEGER) : CARDINAL;
  802. *
  803. *   FUNCTION
  804. *    HeisYearDays gives you back the number of days in
  805. *    a specified year.
  806. *
  807. *   INPUTS
  808. *    year  - The year in which to count the days.
  809. *
  810. *   RESULT
  811. *    days - The number of days the year uses.
  812. *
  813. *   EXAMPLE
  814. *    ...
  815. *    days := HeisYearDays(1994);
  816. *    WriteString("Days of 1994 : ");
  817. *    WriteCard(days,3); WriteLn;
  818. *    ...
  819. *
  820. *   NOTES
  821. *    It is better only to use this function for years from -7 to 8000!
  822. *
  823. *   BUGS
  824. *    No known bugs.
  825. *
  826. *   SEE ALSO
  827. *    HeisMonthDays(),JulianYearDays(),GregorianYearDays()
  828. *
  829. *****************************************************************************
  830. *
  831. *
  832. *)
  833.  
  834.  VAR
  835.     month    : SHORTCARD;
  836.     days    : CARDINAL;
  837.  
  838.  BEGIN
  839.    days := 0;
  840.    FOR month := 1 TO 12 DO (* add the days of all 12 month *)
  841.      days := days + HeisMonthDays(month,year);
  842.    END;
  843.    RETURN(days);
  844.  END HeisYearDays;
  845.  
  846.  (* ----------------------------------------------------------------------- *)
  847.  
  848.  PROCEDURE JulianDaySmaller(day1,month1 : SHORTCARD; year1 : INTEGER;
  849.             day2,month2 : SHORTCARD; year2 : INTEGER) : BOOLEAN;
  850.  
  851. (*
  852. ******* Date/JulianDaySmaller ***********************************************
  853. *
  854. *   NAME
  855. *    JulianDaySmaller -- Checks if date1 is smaller than date2. (V33)
  856. *
  857. *   SYNOPSIS
  858. *    smaller := JulianDaySmaller(day1,month1,year1,day2,month2,year2);
  859. *
  860. *    PROCEDURE JulianDaySmaller(day1,month1 : SHORTCARD; year1 : INTEGER;
  861. *        day2,month2 : SHORTCARD; year2 : INTEGER) : BOOLEAN;
  862. *
  863. *   FUNCTION
  864. *    JulianDaySmaller test if date1 is smaller than date2.
  865. *
  866. *   INPUTS
  867. *    day1   - day of the first date
  868. *    month1 - month of the first date
  869. *    year1  - year of the first date
  870. *    day2   - day of the second date
  871. *    month2 - month of the second month
  872. *    year2  - year of the second date
  873. *
  874. *   RESULT
  875. *    smaller - This is TRUE is date1 < date2 otherwise it's FALSE.
  876. *
  877. *   EXAMPLE
  878. *    ...
  879. *    IF JulianDaySmaller(18,9,1970,22,1,1994) THEN
  880. *      WriteString("<"); WriteLn;
  881. *    ELSE
  882. *      WriteString(">="); WriteLn;
  883. *    END;
  884. *    ...
  885. *
  886. *   NOTES
  887. *    It is better only to use this function for years from -7 to 1582!
  888. *
  889. *   BUGS
  890. *    No known bugs.
  891. *
  892. *   SEE ALSO
  893. *    GregorianDaySmaller(),HeisDaySmaller()
  894. *
  895. *****************************************************************************
  896. *
  897. *
  898. *)
  899.  
  900.  BEGIN
  901.    IF year1 = year2 THEN
  902.      IF month1 = month2 THEN
  903.        RETURN(day1 < day2);
  904.      ELSE
  905.        RETURN(month1 < month2);
  906.      END;
  907.    ELSE
  908.      RETURN(year1 < year2);
  909.    END;
  910.  END JulianDaySmaller;
  911.  
  912.  
  913.  PROCEDURE GregorianDaySmaller(day1,month1 : SHORTCARD; year1 : INTEGER;
  914.             day2,month2 : SHORTCARD; year2 : INTEGER) : BOOLEAN;
  915.  
  916. (*
  917. ******* Date/GregorianDaySmaller ********************************************
  918. *
  919. *   NAME
  920. *    GregorianDaySmaller -- Checks if date1 is smaller than date2. (V33)
  921. *
  922. *   SYNOPSIS
  923. *    smaller := GregorianDaySmaller(day1,month1,year1,day2,month2,year2);
  924. *
  925. *    PROCEDURE GregorianDaySmaller(day1,month1 : SHORTCARD;
  926. *        year1 : INTEGER; day2,month2 : SHORTCARD;
  927. *        year2 : INTEGER) : BOOLEAN;
  928. *
  929. *   FUNCTION
  930. *    GregorianDaySmaller test if date1 is smaller than date2.
  931. *
  932. *   INPUTS
  933. *    day1   - day of the first date
  934. *    month1 - month of the first date
  935. *    year1  - year of the first date
  936. *    day2   - day of the second date
  937. *    month2 - month of the second month
  938. *    year2  - year of the second date
  939. *
  940. *   RESULT
  941. *    smaller - This is TRUE is date1 < date2 otherwise it's FALSE.
  942. *
  943. *   EXAMPLE
  944. *    ...
  945. *    IF GregorianDaySmaller(18,9,1970,22,1,1994) THEN
  946. *      WriteString("<"); WriteLn;
  947. *    ELSE
  948. *      WriteString(">="); WriteLn;
  949. *    END;
  950. *    ...
  951. *
  952. *   NOTES
  953. *    It is better only to use this function for years from -7 to 3200!
  954. *
  955. *   BUGS
  956. *    No known bugs.
  957. *
  958. *   SEE ALSO
  959. *    JulianDaySmaller(),HeisDaySmaller()
  960. *
  961. *****************************************************************************
  962. *
  963. *
  964. *)
  965.  
  966.  BEGIN
  967.    RETURN(JulianDaySmaller(day1,month1,year1,day2,month2,year2));
  968.  END GregorianDaySmaller;
  969.  
  970.  
  971.  PROCEDURE HeisDaySmaller(day1,month1 : SHORTCARD; year1 : INTEGER;
  972.             day2,month2 : SHORTCARD; year2 : INTEGER) : BOOLEAN;
  973.  
  974. (*
  975. ******* Date/HeisDaySmaller *************************************************
  976. *
  977. *   NAME
  978. *    HeisDaySmaller -- Checks if date1 is smaller than date2. (V33)
  979. *
  980. *   SYNOPSIS
  981. *    smaller := HeisDaySmaller(day1,month1,year1,day2,month2,year2);
  982. *
  983. *    PROCEDURE HeisDaySmaller(day1,month1 : SHORTCARD; year1 : INTEGER;
  984. *        day2,month2 : SHORTCARD; year2 : INTEGER) : BOOLEAN;
  985. *
  986. *   FUNCTION
  987. *    HeisDaySmaller test if date1 is smaller than date2.
  988. *
  989. *   INPUTS
  990. *    day1   - day of the first date
  991. *    month1 - month of the first date
  992. *    year1  - year of the first date
  993. *    day2   - day of the second date
  994. *    month2 - month of the second month
  995. *    year2  - year of the second date
  996. *
  997. *   RESULT
  998. *    smaller - This is TRUE is date1 < date2 otherwise it's FALSE.
  999. *
  1000. *   EXAMPLE
  1001. *    ...
  1002. *    IF HeisDaySmaller(18,9,1970,22,1,1994) THEN
  1003. *      WriteString("<"); WriteLn;
  1004. *    ELSE
  1005. *      WriteString(">="); WriteLn;
  1006. *    END;
  1007. *    ...
  1008. *
  1009. *   NOTES
  1010. *    It is better only to use this function for years from -7 to 8000!
  1011. *
  1012. *   BUGS
  1013. *    No known bugs.
  1014. *
  1015. *   SEE ALSO
  1016. *    JulianDaySmaller(),GregorianDaySmaller()
  1017. *
  1018. *****************************************************************************
  1019. *
  1020. *
  1021. *)
  1022.  
  1023.  BEGIN
  1024.    (* To avoid bugs if differences to JulianDaySmaller was found! *)
  1025.    RETURN(GregorianDaySmaller(day1,month1,year1,day2,month2,year2));
  1026.  END HeisDaySmaller;
  1027.  
  1028.  (* ----------------------------------------------------------------------- *)
  1029.  
  1030.  PROCEDURE JulianDayGreater(day1,month1 : SHORTCARD; year1 : INTEGER;
  1031.             day2,month2 : SHORTCARD; year2 : INTEGER) : BOOLEAN;
  1032.  
  1033. (*
  1034. ******* Date/JulianDayGreater ***********************************************
  1035. *
  1036. *   NAME
  1037. *    JulianDayGreater -- Checks if date1 is greater than date2. (V33)
  1038. *
  1039. *   SYNOPSIS
  1040. *    greater := JulianDayGreater(day1,month1,year1,day2,month2,year2);
  1041. *
  1042. *    PROCEDURE JulianDayGreater(day1,month1 : SHORTCARD; year1 : INTEGER;
  1043. *        day2,month2 : SHORTCARD; year2 : INTEGER) : BOOLEAN;
  1044. *
  1045. *   FUNCTION
  1046. *    JulianDayGreater test if date1 is greater than date2.
  1047. *
  1048. *   INPUTS
  1049. *    day1   - day of the first date
  1050. *    month1 - month of the first date
  1051. *    year1  - year of the first date
  1052. *    day2   - day of the second date
  1053. *    month2 - month of the second month
  1054. *    year2  - year of the second date
  1055. *
  1056. *   RESULT
  1057. *    greater - This is TRUE is date1 > date2 otherwise it's FALSE.
  1058. *
  1059. *   EXAMPLE
  1060. *    ...
  1061. *    IF JulianDayGreater(18,9,1970,22,1,1994) THEN
  1062. *      WriteString(">"); WriteLn;
  1063. *    ELSE
  1064. *      WriteString("<="); WriteLn;
  1065. *    END;
  1066. *    ...
  1067. *
  1068. *   NOTES
  1069. *    It is better only to use this function for years from -7 to 1582!
  1070. *
  1071. *   BUGS
  1072. *    No known bugs.
  1073. *
  1074. *   SEE ALSO
  1075. *    GregorianDayGreater(),HeisDayGreater()
  1076. *
  1077. *****************************************************************************
  1078. *
  1079. *
  1080. *)
  1081.  
  1082.  BEGIN
  1083.    IF year1 = year2 THEN
  1084.      IF month1 = month2 THEN
  1085.        RETURN(day1 > day2);
  1086.      ELSE
  1087.        RETURN(month1 > month2);
  1088.      END;
  1089.    ELSE
  1090.      RETURN(year1 > year2);
  1091.    END;
  1092.  END JulianDayGreater;
  1093.  
  1094.  
  1095.  PROCEDURE GregorianDayGreater(day1,month1 : SHORTCARD; year1 : INTEGER;
  1096.             day2,month2 : SHORTCARD; year2 : INTEGER) : BOOLEAN;
  1097.  
  1098. (*
  1099. ******* Date/GregorianDayGreater ********************************************
  1100. *
  1101. *   NAME
  1102. *    GregorianDayGreater -- Checks if date1 is greater than date2. (V33)
  1103. *
  1104. *   SYNOPSIS
  1105. *    greater := GregorianDayGreater(day1,month1,year1,day2,month2,year2);
  1106. *
  1107. *    PROCEDURE GregorianDayGreater(day1,month1 : SHORTCARD;
  1108. *        year1 : INTEGER; day2,month2 : SHORTCARD;
  1109. *        year2 : INTEGER) : BOOLEAN;
  1110. *
  1111. *   FUNCTION
  1112. *    GregorianDayGreater test if date1 is greater than date2.
  1113. *
  1114. *   INPUTS
  1115. *    day1   - day of the first date
  1116. *    month1 - month of the first date
  1117. *    year1  - year of the first date
  1118. *    day2   - day of the second date
  1119. *    month2 - month of the second month
  1120. *    year2  - year of the second date
  1121. *
  1122. *   RESULT
  1123. *    greater - This is TRUE is date1 > date2 otherwise it's FALSE.
  1124. *
  1125. *   EXAMPLE
  1126. *    ...
  1127. *    IF GregorianDayGreater(18,9,1970,22,1,1994) THEN
  1128. *      WriteString(">"); WriteLn;
  1129. *    ELSE
  1130. *      WriteString("<="); WriteLn;
  1131. *    END;
  1132. *    ...
  1133. *
  1134. *   NOTES
  1135. *    It is better only to use this function for years from -7 to 3200!
  1136. *
  1137. *   BUGS
  1138. *    No known bugs.
  1139. *
  1140. *   SEE ALSO
  1141. *    JuliandayGreater(),HeisDayGreater()
  1142. *
  1143. *****************************************************************************
  1144. *
  1145. *
  1146. *)
  1147.  
  1148.  BEGIN
  1149.    RETURN(JulianDayGreater(day1,month1,year1,day2,month2,year2));
  1150.  END GregorianDayGreater;
  1151.  
  1152.  
  1153.  PROCEDURE HeisDayGreater(day1,month1 : SHORTCARD; year1 : INTEGER;
  1154.             day2,month2 : SHORTCARD; year2 : INTEGER) : BOOLEAN;
  1155.  
  1156. (*
  1157. ******* Date/HeisDayGreater *************************************************
  1158. *
  1159. *   NAME
  1160. *    HeisDayGreater -- Checks if date1 is greater than date2. (V33)
  1161. *
  1162. *   SYNOPSIS
  1163. *    greater := HeisDayGreater(day1,month1,year1,day2,month2,year2);
  1164. *
  1165. *    PROCEDURE HeisDayGreater(day1,month1 : SHORTCARD; year1 : INTEGER;
  1166. *        day2,month2 : SHORTCARD; year2 : INTEGER) : BOOLEAN;
  1167. *
  1168. *   FUNCTION
  1169. *    HeisDayGreater test if date1 is greater than date2.
  1170. *
  1171. *   INPUTS
  1172. *    day1   - day of the first date
  1173. *    month1 - month of the first date
  1174. *    year1  - year of the first date
  1175. *    day2   - day of the second date
  1176. *    month2 - month of the second month
  1177. *    year2  - year of the second date
  1178. *
  1179. *   RESULT
  1180. *    greater - This is TRUE is date1 > date2 otherwise it's FALSE.
  1181. *
  1182. *   EXAMPLE
  1183. *    ...
  1184. *    IF HeisDayGreater(18,9,1970,22,1,1994) THEN
  1185. *      WriteString(">"); WriteLn;
  1186. *    ELSE
  1187. *      WriteString("<="); WriteLn;
  1188. *    END;
  1189. *    ...
  1190. *
  1191. *   NOTES
  1192. *    It is better only to use this function for years from -7 to 8000!
  1193. *
  1194. *   BUGS
  1195. *    No known bugs.
  1196. *
  1197. *   SEE ALSO
  1198. *    JulianDayGreater(),GregorianDayGreater()
  1199. *
  1200. *****************************************************************************
  1201. *
  1202. *
  1203. *)
  1204.  
  1205.  BEGIN
  1206.    (* To avoid bugs if differences to JulianDayGreater was found! *)
  1207.    RETURN(GregorianDayGreater(day1,month1,year1,day2,month2,year2));
  1208.  END HeisDayGreater;
  1209.  
  1210.  (* ----------------------------------------------------------------------- *)
  1211.  
  1212.  PROCEDURE JulianDayDiff(day1,month1 : SHORTCARD; year1 : INTEGER;
  1213.             day2,month2 : SHORTCARD; year2 : INTEGER) : LONGINT;
  1214.  
  1215. (*
  1216. ******* Date/JulianDayDiff **************************************************
  1217. *
  1218. *   NAME
  1219. *    JulianDayDiff -- Calculates the days between 2 dates. (V33)
  1220. *
  1221. *   SYNOPSIS
  1222. *    days := JulianDayDiff(day1,month1,year1,day2,month2,year2);
  1223. *
  1224. *    PROCEDURE JulianDayDiff(day1,month1 : SHORTCARD; year1 : INTEGER;
  1225. *        day2,month2 : SHORTCARD; year2 : INTEGER) : LONGINT;
  1226. *
  1227. *   FUNCTION
  1228. *    JulianDayDiff gives you back the number of days between
  1229. *    two specified dates.
  1230. *
  1231. *   INPUTS
  1232. *    day1   - day of the first date
  1233. *    month1 - month of the first date
  1234. *    year1  - year of the first date
  1235. *    day2   - day of the second date
  1236. *    month2 - month of the second month
  1237. *    year2  - year of the second date
  1238. *
  1239. *   RESULT
  1240. *    days - The number of days between the two dates
  1241. *        (positive if date1 <= date2).
  1242. *
  1243. *   EXAMPLE
  1244. *    ...
  1245. *    days := JulianDayDiff(18,9,1970,22,1,1994);
  1246. *    WriteString("Age of Kai Hofmann in days : ");
  1247. *    WriteInt(days,10); WriteLn;
  1248. *    ...
  1249. *
  1250. *   NOTES
  1251. *    It is better only to use this function for years from -7 to 1582!
  1252. *
  1253. *   BUGS
  1254. *    No known bugs.
  1255. *
  1256. *   SEE ALSO
  1257. *    GregorianDayDiff(),HeisDayDiff(),JulianMonthDays(),JulianYearDays()
  1258. *
  1259. *****************************************************************************
  1260. *
  1261. *
  1262. *)
  1263.  
  1264.  VAR
  1265.     t1,t2 : LONGCARD;
  1266.  
  1267.  BEGIN
  1268.    t1 := day1; (* set days left in the actual month *)
  1269.    t2 := day2;
  1270.  
  1271.    WHILE month1 > 1 DO (* calc days left by the gone month of the year1 *)
  1272.      DEC(month1);
  1273.      t1 := t1 + JulianMonthDays(month1,year1);
  1274.    END;
  1275.  
  1276.    WHILE month2 > 1 DO (* calc days left by the gone month of the year2 *)
  1277.      DEC(month2);
  1278.      t2 := t2 + JulianMonthDays(month2,year2);
  1279.    END;
  1280.  
  1281.    WHILE year1 > year2 DO (* calc days of diff years *)
  1282.      DEC(year1);
  1283.      t1 := t1 + JulianYearDays(year1);
  1284.    END;
  1285.  
  1286.    WHILE year1 < year2 DO (* calc days of diff years *)
  1287.      DEC(year2);
  1288.      t2 := t2 + JulianYearDays(year2);
  1289.    END;
  1290.  
  1291.    RETURN(LONGINT(t2)-LONGINT(t1));
  1292.  END JulianDayDiff;
  1293.  
  1294.  
  1295.  PROCEDURE GregorianDayDiff(day1,month1 : SHORTCARD; year1 : INTEGER;
  1296.             day2,month2 : SHORTCARD; year2 : INTEGER) : LONGINT;
  1297.  
  1298. (*
  1299. ******* Date/GregorianDayDiff ***********************************************
  1300. *
  1301. *   NAME
  1302. *    GregorianDayDiff -- Calculates the days between 2 dates. (V33)
  1303. *
  1304. *   SYNOPSIS
  1305. *    days := GregorianDayDiff(day1,month1,year1,day2,month2,year2);
  1306. *
  1307. *    PROCEDURE GregorianDayDiff(day1,month1 : SHORTCARD; year1 : INTEGER;
  1308. *        day2,month2 : SHORTCARD; year2 : INTEGER) : LONGINT;
  1309. *
  1310. *   FUNCTION
  1311. *    GregorianDayDiff gives you back the number of days between
  1312. *    two specified dates.
  1313. *
  1314. *   INPUTS
  1315. *    day1   - day of the first date
  1316. *    month1 - month of the first date
  1317. *    year1  - year of the first date
  1318. *    day2   - day of the second date
  1319. *    month2 - month of the second month
  1320. *    year2  - year of the second date
  1321. *
  1322. *   RESULT
  1323. *    days - The number of days between the two dates
  1324. *        (positive if date1 <= date2).
  1325. *
  1326. *   EXAMPLE
  1327. *    ...
  1328. *    days := GregorianDayDiff(18,9,1970,22,1,1994);
  1329. *    WriteString("Age of Kai Hofmann in days : ");
  1330. *    WriteInt(days,10); WriteLn;
  1331. *    ...
  1332. *
  1333. *   NOTES
  1334. *    It is better only to use this function for years from -7 to 3200!
  1335. *
  1336. *   BUGS
  1337. *    If you use on of the dates 5.10.1582 to 14.10.1582 you will get a
  1338. *    wrong output, because this days don't exist!
  1339. *
  1340. *   SEE ALSO
  1341. *    JulianDayDiff(),HeisDayDiff(),GregorianDaySmaller(),
  1342. *    GregorianDayGreater(),GregorianMonthDays(),GregorianYearDays()
  1343. *
  1344. *****************************************************************************
  1345. *
  1346. *
  1347. *)
  1348.  
  1349.  VAR
  1350.     t1,t2 : LONGCARD;
  1351.  
  1352.  BEGIN
  1353.    t1 := day1; (* set days left in the actual month *)
  1354.    t2 := day2;
  1355.  
  1356.    IF (year1 = 1582) AND (month1 = 10) THEN
  1357.      IF (day1 < 5) AND GregorianDaySmaller(day1,month1,year1,day2,month2,year2) AND GregorianDaySmaller(day2,month2,year2,1,11,1582) AND GregorianDayGreater(day2,month2,year2,14,10,1582) THEN
  1358.        t2 := t2 - 10;
  1359.      END;
  1360.      IF day1 > 14 THEN
  1361.        IF GregorianDaySmaller(day1,month1,year1,day2,month2,year2) AND GregorianDayGreater(day2,month2,year2,31,10,1582) THEN
  1362.          t2 := t2 +10;
  1363.        END;
  1364.        IF GregorianDayGreater(day1,month1,year1,day2,month2,year2) AND GregorianDaySmaller(day2,month2,year2,5,10,1582) THEN
  1365.          t1 := t1 -10;
  1366.        END;
  1367.      END;
  1368.    END;
  1369.  
  1370.    IF (year2 = 1582) AND (month2 = 10) AND (day2 > 14) THEN
  1371.      IF GregorianDaySmaller(day2,month2,year2,day1,month1,year1) AND GregorianDayGreater(day1,month1,year1,31,10,1582) THEN
  1372.        t1 := t1 +10;
  1373.      END;
  1374.      IF GregorianDayGreater(day2,month2,year2,day1,month1,year1) AND GregorianDaySmaller(day1,month1,year1,1,10,1582) THEN
  1375.        t2 := t2 -10;
  1376.      END;
  1377.    END;
  1378.  
  1379.    WHILE month1 > 1 DO (* calc days left by the gone month of the year1 *)
  1380.      DEC(month1);
  1381.      t1 := t1 + GregorianMonthDays(month1,year1);
  1382.    END;
  1383.  
  1384.    WHILE month2 > 1 DO (* calc days left by the gone month of the year2 *)
  1385.      DEC(month2);
  1386.      t2 := t2 + GregorianMonthDays(month2,year2);
  1387.    END;
  1388.  
  1389.    WHILE year1 > year2 DO (* calc days of diff years *)
  1390.      DEC(year1);
  1391.      t1 := t1 + GregorianYearDays(year1);
  1392.    END;
  1393.  
  1394.    WHILE year1 < year2 DO (* calc days of diff years *)
  1395.      DEC(year2);
  1396.      t2 := t2 + GregorianYearDays(year2);
  1397.    END;
  1398.  
  1399.    RETURN(LONGINT(t2)-LONGINT(t1));
  1400.  END GregorianDayDiff;
  1401.  
  1402.  
  1403.  PROCEDURE HeisDayDiff(day1,month1 : SHORTCARD; year1 : INTEGER;
  1404.             day2,month2 : SHORTCARD; year2 : INTEGER) : LONGINT;
  1405.  
  1406. (*
  1407. ******* Date/HeisDayDiff ****************************************************
  1408. *
  1409. *   NAME
  1410. *    HeisDayDiff -- Calculates the days between 2 dates. (V33)
  1411. *
  1412. *   SYNOPSIS
  1413. *    days := HeisDayDiff(day1,month1,year1,day2,month2,year2);
  1414. *
  1415. *    PROCEDURE HeisDayDiff(day1,month1 : SHORTCARD; year1 : INTEGER;
  1416. *        day2,month2 : SHORTCARD; year2 : INTEGER) : LONGINT;
  1417. *
  1418. *   FUNCTION
  1419. *    HeisDayDiff gives you back the number of days between
  1420. *    two specified dates.
  1421. *
  1422. *   INPUTS
  1423. *    day1   - day of the first date
  1424. *    month1 - month of the first date
  1425. *    year1  - year of the first date
  1426. *    day2   - day of the second date
  1427. *    month2 - month of the second month
  1428. *    year2  - year of the second date
  1429. *
  1430. *   RESULT
  1431. *    days - The number of days between the two dates
  1432. *        (positive if date1 <= date2).
  1433. *
  1434. *   EXAMPLE
  1435. *    ...
  1436. *    days := HeisDayDiff(18,9,1970,22,1,1994);
  1437. *    WriteString("Age of Kai Hofmann in days : ");
  1438. *    WriteInt(days,10); WriteLn;
  1439. *    ...
  1440. *
  1441. *   NOTES
  1442. *    It is better only to use this function for years from -7 to 8000!
  1443. *
  1444. *   BUGS
  1445. *    If you use on of the dates 5.10.1582 to 14.10.1582 you will get a
  1446. *    wrong output, because this days don't exist!
  1447. *
  1448. *   SEE ALSO
  1449. *    JulianDayDiff(),GregorianDayDiff(),HeisDaySmaller(),HeisDayGreater(),
  1450. *    HeisMonthDays(),HeisYearDays()
  1451. *
  1452. *****************************************************************************
  1453. *
  1454. *
  1455. *)
  1456.  
  1457.  VAR
  1458.     t1,t2 : LONGCARD;
  1459.  
  1460.  BEGIN
  1461.    t1 := day1; (* set days left in the actual month *)
  1462.    t2 := day2;
  1463.  
  1464.    IF (year1 = 1582) AND (month1 = 10) THEN
  1465.      IF (day1 < 5) AND HeisDaySmaller(day1,month1,year1,day2,month2,year2) AND HeisDaySmaller(day2,month2,year2,1,11,1582) AND HeisDayGreater(day2,month2,year2,14,10,1582) THEN
  1466.        t2 := t2 - 10;
  1467.      END;
  1468.      IF day1 > 14 THEN
  1469.        IF HeisDaySmaller(day1,month1,year1,day2,month2,year2) AND HeisDayGreater(day2,month2,year2,31,10,1582) THEN
  1470.          t2 := t2 +10;
  1471.        END;
  1472.        IF HeisDayGreater(day1,month1,year1,day2,month2,year2) AND HeisDaySmaller(day2,month2,year2,5,10,1582) THEN
  1473.          t1 := t1 -10;
  1474.        END;
  1475.      END;
  1476.    END;
  1477.  
  1478.    IF (year2 = 1582) AND (month2 = 10) AND (day2 > 14) THEN
  1479.      IF HeisDaySmaller(day2,month2,year2,day1,month1,year1) AND HeisDayGreater(day1,month1,year1,31,10,1582) THEN
  1480.        t1 := t1 +10;
  1481.      END;
  1482.      IF HeisDayGreater(day2,month2,year2,day1,month1,year1) AND HeisDaySmaller(day1,month1,year1,1,10,1582) THEN
  1483.        t2 := t2 -10;
  1484.      END;
  1485.    END;
  1486.  
  1487.    WHILE month1 > 1 DO (* calc days left by the gone month of the year1 *)
  1488.      DEC(month1);
  1489.      t1 := t1 + HeisMonthDays(month1,year1);
  1490.    END;
  1491.  
  1492.    WHILE month2 > 1 DO (* calc days left by the gone month of the year2 *)
  1493.      DEC(month2);
  1494.      t2 := t2 + HeisMonthDays(month2,year2);
  1495.    END;
  1496.  
  1497.    WHILE year1 > year2 DO (* calc days of diff years *)
  1498.      DEC(year1);
  1499.      t1 := t1 + HeisYearDays(year1);
  1500.    END;
  1501.  
  1502.    WHILE year1 < year2 DO (* calc days of diff years *)
  1503.      DEC(year2);
  1504.      t2 := t2 + HeisYearDays(year2);
  1505.    END;
  1506.  
  1507.    RETURN(LONGINT(t2)-LONGINT(t1));
  1508.  END HeisDayDiff;
  1509.  
  1510.  (* ----------------------------------------------------------------------- *)
  1511.  
  1512.  PROCEDURE JulianWeekday(day,month : SHORTCARD; year : INTEGER) : Weekdays;
  1513.  
  1514. (*
  1515. ******* Date/JulianWeekday **************************************************
  1516. *
  1517. *   NAME
  1518. *    JulianWeekday -- Gets the weekday of a specified date. (V33)
  1519. *
  1520. *   SYNOPSIS
  1521. *    weekday := JulianWeekday(day,month,year);
  1522. *
  1523. *    PROCEDURE JulianWeekday(day,month : SHORTCARD;
  1524. *        year : INTEGER) : Weekday;
  1525. *
  1526. *   FUNCTION
  1527. *    JulianWeekday gets the weekday for a specified date.
  1528. *
  1529. *   INPUTS
  1530. *    day   - day of the date
  1531. *    month - month of the date
  1532. *    year  - year of the date
  1533. *
  1534. *   RESULT
  1535. *    weekday - This result is of type:
  1536. *        Weekdays := (dayerr,Monday,Tuesday,Wednesday,Thursday,Friday,
  1537. *        Saturday,Sunday);
  1538. *        dayerr will show you, that an error occurs!
  1539. *
  1540. *   EXAMPLE
  1541. *    ...
  1542. *    weekday := JulianWeekday(4,10,1582);
  1543. *    IF weekday = dayerr THEN
  1544. *    ...
  1545. *    END;
  1546. *    ...
  1547. *
  1548. *   NOTES
  1549. *    It is better only to use this function for years from 0 to 1582!
  1550. *    In this version no dayerr will occur!
  1551. *
  1552. *   BUGS
  1553. *    For years < 0 errors could occur, or systemcrashs(?).
  1554. *
  1555. *   SEE ALSO
  1556. *    GregorianWeekday(),HeisWeekday()
  1557. *
  1558. *****************************************************************************
  1559. *
  1560. *
  1561. *)
  1562.  
  1563.  VAR
  1564.     decade,wday    : SHORTCARD;
  1565.  
  1566.  BEGIN
  1567.    (* January and february dates must be 13 and 14 of the year before! *)
  1568.    IF month IN {1,2} THEN
  1569.      month := 12 + month;
  1570.      DEC(year);
  1571.    END;
  1572.    decade := year - ((year DIV 100) * 100);
  1573.    (* Formula from Ch. Zeller in 1877 *)
  1574.    wday := (day + (((month+1) * 26) DIV 10) + decade + (decade DIV 4)
  1575.                     + 5 - SHORTCARD(year DIV 100)) MOD 7;
  1576.    (* Convert (1-su 2-mo 3-tu 4-we 5-th 6-fr 7/0-sa) to normal days *)
  1577.    IF wday = 0 THEN
  1578.      wday := 6;
  1579.    ELSE
  1580.      DEC(wday);
  1581.      IF wday = 0 THEN
  1582.        wday := 7;
  1583.      END;
  1584.    END;
  1585.    RETURN(Weekdays(wday));
  1586.  END JulianWeekday;
  1587.  
  1588.  
  1589.  PROCEDURE GregorianWeekday(day,month : SHORTCARD; year : INTEGER) : Weekdays;
  1590.  
  1591. (*
  1592. ******* Date/GregorianWeekday ***********************************************
  1593. *
  1594. *   NAME
  1595. *    GregorianWeekday -- Gets the weekday of a specified date. (V33)
  1596. *
  1597. *   SYNOPSIS
  1598. *    weekday := GregorianWeekday(day,month,year);
  1599. *
  1600. *    PROCEDURE GregorianWeekday(day,month : SHORTCARD;
  1601. *        year : INTEGER) : Weekday;
  1602. *
  1603. *   FUNCTION
  1604. *    GregorianWeekday gets the weekday for a specified date.
  1605. *
  1606. *   INPUTS
  1607. *    day   - day of the date
  1608. *    month - month of the date
  1609. *    year  - year of the date
  1610. *
  1611. *   RESULT
  1612. *    weekday - This result is of type:
  1613. *        Weekdays = (dayerr,Monday,Tuesday,Wednesday,Thursday,Friday,
  1614. *        Saturday,Sunday);
  1615. *        dayerr will show you, that an error occurs!
  1616. *
  1617. *   EXAMPLE
  1618. *    ...
  1619. *    weekday := GregorianWeekday(22,1,1994);
  1620. *    IF weekday = dayerr THEN
  1621. *    ...
  1622. *    END;
  1623. *    ...
  1624. *
  1625. *   NOTES
  1626. *    It is better only to use this function for years from -7 to 3200!
  1627. *    In this version dayerr will only occur for the 10 lost days :)
  1628. *
  1629. *   BUGS
  1630. *    It's not possible to use years < 0 (for more see JulianWeekday()).
  1631. *
  1632. *   SEE ALSO
  1633. *    JulianWeekday(),HeisWeekday(),GregorianDaySmaller(),
  1634. *    GregorianLeapYear()
  1635. *
  1636. *****************************************************************************
  1637. *
  1638. *
  1639. *)
  1640.  
  1641.  VAR
  1642.     weekday    : Weekdays;
  1643.     wd    : CARDINAL;
  1644.  
  1645.  BEGIN
  1646.    IF GregorianDaySmaller(day,month,year,BeforeGregorianDay+1,
  1647.                 BeforeGregorianMonth,BeforeGregorianYear) THEN
  1648.      RETURN(JulianWeekday(day,month,year));
  1649.    ELSIF GregorianDaySmaller(day,month,year,AfterGregorianDay,
  1650.                 AfterGregorianMonth,AfterGregorianYear) THEN
  1651.      RETURN(dayerr);
  1652.    ELSE
  1653.      (* Formula from J. I. Perelman 1909 *)
  1654.      wd := year + (year DIV 4) - (year DIV 100) + (year DIV 400)
  1655.                 + GregorianDayDiff(1,1,year,day,month,year);
  1656.      IF GregorianLeapYear(year) THEN
  1657.        DEC(wd);
  1658.      END;
  1659.      weekday := Weekdays(wd MOD 7);
  1660.      IF weekday = dayerr THEN
  1661.        weekday := Sunday;
  1662.      END;
  1663.      RETURN(weekday);
  1664.    END;
  1665.  END GregorianWeekday;
  1666.  
  1667.  
  1668.  PROCEDURE HeisWeekday(day,month : SHORTCARD; year : INTEGER) : Weekdays;
  1669.  
  1670. (*
  1671. ******* Date/HeisWeekday ****************************************************
  1672. *
  1673. *   NAME
  1674. *    HeisWeekday -- Gets the weekday of a specified date. (V33)
  1675. *
  1676. *   SYNOPSIS
  1677. *    weekday := HeisWeekday(day,month,year);
  1678. *
  1679. *    PROCEDURE HeisWeekday(day,month : SHORTCARD;
  1680. *        year : INTEGER) : Weekday;
  1681. *
  1682. *   FUNCTION
  1683. *    HeisWeekday gets the weekday for a specified date.
  1684. *
  1685. *   INPUTS
  1686. *    day   - day of the date
  1687. *    month - month of the date
  1688. *    year  - year of the date
  1689. *
  1690. *   RESULT
  1691. *    weekday - This result is of type:
  1692. *        Weekdays = (dayerr,Monday,Tuesday,Wednesday,Thursday,Friday,
  1693. *        Saturday,Sunday);
  1694. *        dayerr will show you, that an error occurs!
  1695. *
  1696. *   EXAMPLE
  1697. *    ...
  1698. *    weekday := HeisWeekday(22,1,1994);
  1699. *    IF weekday = dayerr THEN
  1700. *    ...
  1701. *    END;
  1702. *    ...
  1703. *
  1704. *   NOTES
  1705. *    It is better only to use this function for years from -7 to 8000!
  1706. *    In this version dayerr will only occur for the 10 lost days :)
  1707. *
  1708. *   BUGS
  1709. *    It is not possible to use year < 0 (see JulianWeekday() for more).
  1710. *
  1711. *   SEE ALSO
  1712. *    JulianWeekday(),GregorianWeekday(),HeisDaySmaller(),HeisLeapYear(),
  1713. *    HeisDayDiff()
  1714. *
  1715. *****************************************************************************
  1716. *
  1717. *
  1718. *)
  1719.  
  1720.  VAR
  1721.     weekday    : Weekdays;
  1722.     wd    : CARDINAL;
  1723.  
  1724.  BEGIN
  1725.    IF HeisDaySmaller(day,month,year,StartHeisDay,
  1726.                 StartHeisMonth,StartHeisYear) THEN
  1727.      RETURN(GregorianWeekday(day,month,year));
  1728.    ELSE
  1729.      (* Formula from J. I. Perelman 1909 - extended for N.Heis in 01.1994
  1730.     by Kai Hofmann *)
  1731.      wd := year + (year DIV 4) - (year DIV 100) + (year DIV 400)
  1732.         - (year DIV 3200) + HeisDayDiff(1,1,year,day,month,year);
  1733.      IF HeisLeapYear(year) THEN
  1734.        DEC(wd);
  1735.      END;
  1736.      weekday := Weekdays(wd MOD 7);
  1737.      IF weekday = dayerr THEN
  1738.        weekday := Sunday;
  1739.      END;
  1740.      RETURN(weekday);
  1741.    END;
  1742.  END HeisWeekday;
  1743.  
  1744.  (* ----------------------------------------------------------------------- *)
  1745.  
  1746.  PROCEDURE JulianDaysBeforeWeekday(day,month : SHORTCARD;
  1747.             year : INTEGER; weekday : Weekdays) : SHORTCARD;
  1748.  
  1749. (*
  1750. ******* Date/JulianDaysBeforeWeekday ****************************************
  1751. *
  1752. *   NAME
  1753. *    JulianDaysBeforeWeekday -- Returns the diff to the wday before. (V33)
  1754. *
  1755. *   SYNOPSIS
  1756. *    days := JulianDaysBeforeWeekday(day,month,year,weekday);
  1757. *
  1758. *    PROCEDURE JulianDaysBeforeWeekday(day,month : SHORTCARD;
  1759. *        year : INTEGER; weekday : Weekdays) : SHORTCARD;
  1760. *
  1761. *   FUNCTION
  1762. *    Returns the days to the weekday before the specified date.
  1763. *    So if you specify the 22.1.1994 (Saturday) and Thursday
  1764. *    you get back 2!
  1765. *    If you specify the 22.1.1994 and Saturday you get back 0
  1766. *    (the same day)!
  1767. *
  1768. *   INPUTS
  1769. *    day     - day of the date
  1770. *    month   - month of the date
  1771. *    year    - year of the date
  1772. *    weekday - weekday to search for building difference
  1773. *
  1774. *   RESULT
  1775. *    days - The days back to the searched weekday (0-6)
  1776. *        If you get back 8 an error occurs!
  1777. *
  1778. *   EXAMPLE
  1779. *    ...
  1780. *    days := JulianDaysBeforeWeekday(22,1,1994,Thursday);
  1781. *    ...
  1782. *
  1783. *   NOTES
  1784. *    It is better to use this function only from -7 to 1582!
  1785. *
  1786. *   BUGS
  1787. *    See JulianWeekday()!
  1788. *
  1789. *   SEE ALSO
  1790. *    GregorianDaysBeforeWeekday(),HeisDaysBeforeWeekday(),JulianWeekday()
  1791. *
  1792. *****************************************************************************
  1793. *
  1794. *
  1795. *)
  1796.  
  1797.  VAR
  1798.     wday    : Weekdays;
  1799.  
  1800.  BEGIN
  1801.    IF weekday = dayerr THEN
  1802.      RETURN(8);
  1803.    ELSE
  1804.      wday := JulianWeekday(day,month,year);
  1805.      IF wday >= weekday THEN
  1806.        RETURN(SHORTCARD(wday)-SHORTCARD(weekday));
  1807.      ELSE (* wday < weekday *)
  1808.        RETURN(7-SHORTCARD(weekday)+SHORTCARD(wday));
  1809.      END;
  1810.    END;
  1811.  END JulianDaysBeforeWeekday;
  1812.  
  1813.  
  1814.  PROCEDURE GregorianDaysBeforeWeekday(day,month : SHORTCARD;
  1815.             year : INTEGER; weekday : Weekdays) : SHORTCARD;
  1816.  
  1817. (*
  1818. ******* Date/GregorianDaysBeforeWeekday *************************************
  1819. *
  1820. *   NAME
  1821. *    GregorianDaysBeforeWeekday -- Returns the diff to wday before. (V33)
  1822. *
  1823. *   SYNOPSIS
  1824. *    days := GregorianDaysBeforeWeekday(day,month,year,weekday);
  1825. *
  1826. *    PROCEDURE GregorianDaysBeforeWeekday(day,month : SHORTCARD;
  1827. *        year : INTEGER; weekday : Weekdays) : SHORTCARD;
  1828. *
  1829. *   FUNCTION
  1830. *    Returns the days to the weekday before the specified date.
  1831. *    So if you specify the 22.1.1994 (Saturday) and Thursday
  1832. *    you get back 2!
  1833. *    If you specify the 22.1.1994 and Saturday you get back 0
  1834. *    (the same day)!
  1835. *
  1836. *   INPUTS
  1837. *    day     - day of the date
  1838. *    month   - month of the date
  1839. *    year    - year of the date
  1840. *    weekday - weekday to search for building difference
  1841. *
  1842. *   RESULT
  1843. *    days - The days back to the searched weekday (1-7)
  1844. *        If you get back 8 an error occurs!
  1845. *
  1846. *   EXAMPLE
  1847. *    ...
  1848. *    days := GregorianDaysBeforeWeekday(22,1,1994,Thursday);
  1849. *    ...
  1850. *
  1851. *   NOTES
  1852. *    It is better to use this function only from -7 to 3200!
  1853. *
  1854. *   BUGS
  1855. *    See GregorianWeekday()!
  1856. *
  1857. *   SEE ALSO
  1858. *    JulianDaysBeforeWeekday(),HeisDaysBeforeWeekday(),GregorianWeekday()
  1859. *
  1860. *****************************************************************************
  1861. *
  1862. *
  1863. *)
  1864.  
  1865.  VAR
  1866.     wday    : Weekdays;
  1867.  
  1868.  BEGIN
  1869.    IF weekday = dayerr THEN
  1870.      RETURN(8);
  1871.    ELSE
  1872.      wday := GregorianWeekday(day,month,year);
  1873.      IF wday >= weekday THEN
  1874.        RETURN(SHORTCARD(wday)-SHORTCARD(weekday));
  1875.      ELSE (* wday < weekday *)
  1876.        RETURN(7-SHORTCARD(weekday)+SHORTCARD(wday));
  1877.      END;
  1878.    END;
  1879.  END GregorianDaysBeforeWeekday;
  1880.  
  1881.  
  1882.  PROCEDURE HeisDaysBeforeWeekday(day,month : SHORTCARD;
  1883.             year : INTEGER; weekday : Weekdays) : SHORTCARD;
  1884.  
  1885. (*
  1886. ******* Date/HeisDaysBeforeWeekday ******************************************
  1887. *
  1888. *   NAME
  1889. *    HeisDaysBeforeWeekday -- Returns the diff to wday before. (V33)
  1890. *
  1891. *   SYNOPSIS
  1892. *    days := HeisDaysBeforeWeekday(day,month,year,weekday);
  1893. *
  1894. *    PROCEDURE HeisDaysBeforeWeekday(day,month : SHORTCARD;
  1895. *        year : INTEGER; weekday : Weekdays) : SHORTCARD;
  1896. *
  1897. *   FUNCTION
  1898. *    Returns the days to the weekday before the specified date.
  1899. *    So if you specify the 22.1.1994 (Saturday) and Thursday
  1900. *    you get back 2!
  1901. *    If you specify the 22.1.1994 and Saturday you get back 0
  1902. *    (the same day)!
  1903. *
  1904. *   INPUTS
  1905. *    day     - day of the date
  1906. *    month   - month of the date
  1907. *    year    - year of the date
  1908. *    weekday - weekday to search for building difference
  1909. *
  1910. *   RESULT
  1911. *    days - The days back to the searched weekday (1-7)
  1912. *        If you get back 8 an error occurs!
  1913. *
  1914. *   EXAMPLE
  1915. *    ...
  1916. *    days := HeisDaysBeforeWeekday(22,1,1994,Thursday);
  1917. *    ...
  1918. *
  1919. *   NOTES
  1920. *    It is better to use this function only from -7 to 8000!
  1921. *
  1922. *   BUGS
  1923. *    See HeisWeekday()!
  1924. *
  1925. *   SEE ALSO
  1926. *    JulianDaysBeforeWeekday(),GregorianDaysBeforeWeekday(),HeisWeekday()
  1927. *
  1928. *****************************************************************************
  1929. *
  1930. *
  1931. *)
  1932.  
  1933.  VAR
  1934.     wday    : Weekdays;
  1935.  
  1936.  BEGIN
  1937.    IF weekday = dayerr THEN
  1938.      RETURN(8);
  1939.    ELSE
  1940.      wday := HeisWeekday(day,month,year);
  1941.      IF wday >= weekday THEN
  1942.        RETURN(SHORTCARD(wday)-SHORTCARD(weekday));
  1943.      ELSE (* wday < weekday *)
  1944.        RETURN(7-SHORTCARD(weekday)+SHORTCARD(wday));
  1945.      END;
  1946.    END;
  1947.  END HeisDaysBeforeWeekday;
  1948.  
  1949.  (* ----------------------------------------------------------------------- *)
  1950.  
  1951.  PROCEDURE JulianDaysAfterWeekday(day,month : SHORTCARD;
  1952.             year : INTEGER; weekday : Weekdays) : SHORTCARD;
  1953.  
  1954. (*
  1955. ******* Date/JulianDaysAfterWeekday *****************************************
  1956. *
  1957. *   NAME
  1958. *    JulianDaysAfterWeekday -- Returns the diff to the wday after. (V33)
  1959. *
  1960. *   SYNOPSIS
  1961. *    days := JulianDaysAfterWeekday(day,month,year,weekday);
  1962. *
  1963. *    PROCEDURE JulianDaysAfterWeekday(day,month : SHORTCARD;
  1964. *        year : INTEGER; weekday : Weekdays) : SHORTCARD;
  1965. *
  1966. *   FUNCTION
  1967. *    Returns the days to the weekday after the specified date.
  1968. *    So if you specify the 22.1.1994 (Saturday) and Thursday
  1969. *    you get back 5!
  1970. *    If you specify the 22.1.1994 and Saturday you get back 0
  1971. *    (the same day)!
  1972. *
  1973. *   INPUTS
  1974. *    day     - day of the date
  1975. *    month   - month of the date
  1976. *    year    - year of the date
  1977. *    weekday - weekday to search for building difference
  1978. *
  1979. *   RESULT
  1980. *    days - The days after to the searched weekday.
  1981. *
  1982. *   EXAMPLE
  1983. *    ...
  1984. *    days := JulianDaysAfterWeekday(22,1,1994,Thursday);
  1985. *    ...
  1986. *
  1987. *   NOTES
  1988. *    It is better to use this function only from -7 to 1582!
  1989. *
  1990. *   BUGS
  1991. *    See JulianWeekday()!
  1992. *
  1993. *   SEE ALSO
  1994. *    GregorianDaysAfterWeekday(),HeisDaysAfterWeekday(),JulianWeekday()
  1995. *
  1996. *****************************************************************************
  1997. *
  1998. *
  1999. *)
  2000.  
  2001.  VAR
  2002.     wday    : Weekdays;
  2003.  
  2004.  BEGIN
  2005.    IF weekday = dayerr THEN
  2006.      RETURN(8);
  2007.    ELSE
  2008.      wday := JulianWeekday(day,month,year);
  2009.      IF wday <= weekday THEN
  2010.        RETURN(SHORTCARD(weekday)-SHORTCARD(wday));
  2011.      ELSE (* wday > weekday *)
  2012.        RETURN(7-SHORTCARD(wday)+SHORTCARD(weekday));
  2013.      END;
  2014.    END;
  2015.  END JulianDaysAfterWeekday;
  2016.  
  2017.  
  2018.  PROCEDURE GregorianDaysAfterWeekday(day,month : SHORTCARD;
  2019.             year : INTEGER; weekday : Weekdays) : SHORTCARD;
  2020.  
  2021. (*
  2022. ******* Date/GregorianDaysAfterWeekday **************************************
  2023. *
  2024. *   NAME
  2025. *    GregorianDaysAfterWeekday -- Returns the diff to wday after. (V33)
  2026. *
  2027. *   SYNOPSIS
  2028. *    days := GregorianDaysAfterWeekday(day,month,year,weekday);
  2029. *
  2030. *    PROCEDURE GregorianDaysAfterWeekday(day,month : SHORTCARD;
  2031. *        year : INTEGER; weekday : Weekdays) : SHORTCARD;
  2032. *
  2033. *   FUNCTION
  2034. *    Returns the days to the weekday after the specified date.
  2035. *    So if you specify the 22.1.1994 (Saturday) and Thursday
  2036. *    you get back 5!
  2037. *    If you specify the 22.1.1994 and Saturday you get back 0
  2038. *    (the same day)!
  2039. *
  2040. *   INPUTS
  2041. *    day     - day of the date
  2042. *    month   - month of the date
  2043. *    year    - year of the date
  2044. *    weekday - weekday to search for building difference
  2045. *
  2046. *   RESULT
  2047. *    days - The days after to the searched weekday.
  2048. *
  2049. *   EXAMPLE
  2050. *    ...
  2051. *    days := GregorianDaysAfterWeekday(22,1,1994,Thursday);
  2052. *    ...
  2053. *
  2054. *   NOTES
  2055. *    It is better to use this function only from -7 to 3200!
  2056. *
  2057. *   BUGS
  2058. *    See GregorianWeekday()!
  2059. *
  2060. *   SEE ALSO
  2061. *    JulianDaysAfterWeekday(),HeisDaysAfterWeekday(),GregorianWeekday()
  2062. *
  2063. *****************************************************************************
  2064. *
  2065. *
  2066. *)
  2067.  
  2068.  VAR
  2069.     wday    : Weekdays;
  2070.  
  2071.  BEGIN
  2072.    IF weekday = dayerr THEN
  2073.      RETURN(8);
  2074.    ELSE
  2075.      wday := GregorianWeekday(day,month,year);
  2076.      IF wday <= weekday THEN
  2077.        RETURN(SHORTCARD(weekday)-SHORTCARD(wday));
  2078.      ELSE (* wday > weekday *)
  2079.        RETURN(7-SHORTCARD(wday)+SHORTCARD(weekday));
  2080.      END;
  2081.    END;
  2082.  END GregorianDaysAfterWeekday;
  2083.  
  2084.  
  2085.  PROCEDURE HeisDaysAfterWeekday(day,month : SHORTCARD;
  2086.             year : INTEGER; weekday : Weekdays) : SHORTCARD;
  2087.  
  2088. (*
  2089. ******* Date/HeisDaysAfterWeekday *******************************************
  2090. *
  2091. *   NAME
  2092. *    HeisDaysAfterWeekday -- Returns the diff to the wday after. (V33)
  2093. *
  2094. *   SYNOPSIS
  2095. *    days := HeisDaysAfterWeekday(day,month,year,weekday);
  2096. *
  2097. *    PROCEDURE HeisDaysAfterWeekday(day,month : SHORTCARD;
  2098. *        year : INTEGER; weekday : Weekdays) : SHORTCARD;
  2099. *
  2100. *   FUNCTION
  2101. *    Returns the days to the weekday after the specified date.
  2102. *    So if you specify the 22.1.1994 (Saturday) and Thursday
  2103. *    you get back 5!
  2104. *    If you specify the 22.1.1994 and Saturday you get back 0
  2105. *    (the same day)!
  2106. *
  2107. *   INPUTS
  2108. *    day     - day of the date
  2109. *    month   - month of the date
  2110. *    year    - year of the date
  2111. *    weekday - weekday to search for building difference
  2112. *
  2113. *   RESULT
  2114. *    days - The days after to the searched weekday.
  2115. *
  2116. *   EXAMPLE
  2117. *    ...
  2118. *    days := HeisDaysAfterWeekday(22,1,1994,Thursday);
  2119. *    ...
  2120. *
  2121. *   NOTES
  2122. *    It is better to use this function only from -7 to 8000!
  2123. *
  2124. *   BUGS
  2125. *    See HeisWeekday()!
  2126. *
  2127. *   SEE ALSO
  2128. *    JulianDaysAfterWeekday(),GregorianDaysAfterWeekday(),HeisWeekday()
  2129. *
  2130. *****************************************************************************
  2131. *
  2132. *
  2133. *)
  2134.  
  2135.  VAR
  2136.     wday    : Weekdays;
  2137.  
  2138.  BEGIN
  2139.    IF weekday = dayerr THEN
  2140.      RETURN(8);
  2141.    ELSE
  2142.      wday := HeisWeekday(day,month,year);
  2143.      IF wday <= weekday THEN
  2144.        RETURN(SHORTCARD(weekday)-SHORTCARD(wday));
  2145.      ELSE (* wday > weekday *)
  2146.        RETURN(7-SHORTCARD(wday)+SHORTCARD(weekday));
  2147.      END;
  2148.    END;
  2149.  END HeisDaysAfterWeekday;
  2150.  
  2151.  (* ----------------------------------------------------------------------- *)
  2152.  
  2153.  PROCEDURE JulianDiffDate(day,month : SHORTCARD;
  2154.     year,days : INTEGER; VAR dday,dmonth : SHORTCARD; VAR dyear : INTEGER);
  2155.  
  2156. (*
  2157. ******* Date/JulianDiffDate *************************************************
  2158. *
  2159. *   NAME
  2160. *    JulianDiffDate -- Returns the date for a diff to another date. (V33)
  2161. *
  2162. *   SYNOPSIS
  2163. *    JulianDiffDate(day,month,year,diffdays,dday,dmonth,dyear);
  2164. *
  2165. *    PROCEDURE JulianDiffDate(day,month : SHORTCARD; year,days : INTEGER;
  2166. *        VAR dday,dmonth : SHORTCARD; VAR dyear : INTEGER);
  2167. *
  2168. *   FUNCTION
  2169. *    Returns the date wich lies diffdays before/after the specified date.
  2170. *
  2171. *   INPUTS
  2172. *    day      - day of the date
  2173. *    month    - month of the date
  2174. *    year     - year of the date
  2175. *    diffdays - difference to the date in days
  2176. *
  2177. *   RESULT
  2178. *    dday   - Destination day
  2179. *    dmonth - Destination month
  2180. *    dyear  - Destination year
  2181. *
  2182. *   EXAMPLE
  2183. *    ...
  2184. *    JulianDiffDate(23,1,1994,7,dday,dmonth,dyear);
  2185. *    ...
  2186. *
  2187. *   NOTES
  2188. *    It is better to use this function only from -7 to 1582!
  2189. *
  2190. *   BUGS
  2191. *    unknown.
  2192. *
  2193. *   SEE ALSO
  2194. *    GregorianDiffDate(),HeisDiffDate(),JulianDayDiff()
  2195. *
  2196. *****************************************************************************
  2197. *
  2198. *
  2199. *)
  2200.  
  2201.  VAR
  2202.     ddays    : INTEGER;
  2203.  
  2204.  BEGIN
  2205.    dday := day;
  2206.    dmonth := month;
  2207.    dyear := year;
  2208.    IF days >= 0 THEN (* add *)
  2209.      ddays := JulianDayDiff(dday,dmonth,dyear,1,1,dyear+1);
  2210.      WHILE days >= ddays DO (* years *)
  2211.        dday := 1;
  2212.        dmonth := 1;
  2213.        INC(dyear);
  2214.        days := days - ddays;
  2215.        ddays := JulianDayDiff(dday,dmonth,dyear,1,1,dyear+1);
  2216.      END;
  2217.      ddays := JulianDayDiff(dday,dmonth,dyear,1,dmonth+1,dyear);
  2218.      WHILE days >= ddays DO (* months *)
  2219.        dday := 1;
  2220.        INC(dmonth);
  2221.        days := days - ddays;
  2222.        ddays := JulianDayDiff(dday,dmonth,dyear,1,dmonth+1,dyear);
  2223.      END;
  2224.      IF days > 0 THEN (* days *)
  2225.        dday := dday + SHORTCARD(days);
  2226.      END;
  2227.    ELSE (* sub *)
  2228.      ddays := JulianDayDiff(dday,dmonth,dyear,31,12,dyear-1);
  2229.      WHILE days <= ddays DO (* years *)
  2230.        dday := 31;
  2231.        dmonth := 12;
  2232.        DEC(dyear);
  2233.        days := days - ddays;
  2234.        ddays := JulianDayDiff(dday,dmonth,dyear,31,12,dyear-1);
  2235.      END;
  2236.      ddays := JulianDayDiff(dday,dmonth,dyear,JulianMonthDays(dmonth-1,dyear),dmonth-1,dyear);
  2237.      WHILE days <= ddays DO (* months *)
  2238.        dday := JulianMonthDays(dmonth-1,dyear);
  2239.        DEC(dmonth);
  2240.        days := days - ddays;
  2241.        ddays := JulianDayDiff(dday,dmonth,dyear,JulianMonthDays(dmonth-1,dyear),dmonth-1,dyear);
  2242.      END;
  2243.      IF days < 0 THEN
  2244.        dday := dday - SHORTCARD(ABS(days));
  2245.      END;
  2246.    END;
  2247.  END JulianDiffDate;
  2248.  
  2249.  
  2250.  PROCEDURE GregorianDiffDate(day,month : SHORTCARD;
  2251.     year,days : INTEGER; VAR dday,dmonth : SHORTCARD; VAR dyear : INTEGER);
  2252.  
  2253. (*
  2254. ******* Date/GregorianDiffDate **********************************************
  2255. *
  2256. *   NAME
  2257. *    GregorianDiffDate -- Returns the diff date to another date. (V33)
  2258. *
  2259. *   SYNOPSIS
  2260. *    GregorianDiffDate(day,month,year,diffdays,dday,dmonth,dyear);
  2261. *
  2262. *    PROCEDURE GregorianDiffDate(day,month : SHORTCARD;
  2263. *        year,days : INTEGER; VAR dday,dmonth : SHORTCARD;
  2264. *        VAR dyear : INTEGER);
  2265. *
  2266. *   FUNCTION
  2267. *    Returns the date wich lies diffdays before/after the specified date.
  2268. *
  2269. *   INPUTS
  2270. *    day      - day of the date
  2271. *    month    - month of the date
  2272. *    year     - year of the date
  2273. *    diffdays - difference to the date in days
  2274. *
  2275. *   RESULT
  2276. *    dday   - Destination day
  2277. *    dmonth - Destination month
  2278. *    dyear  - Destination year
  2279. *
  2280. *   EXAMPLE
  2281. *    ...
  2282. *    GregorianDiffDate(23,1,1994,7,dday,dmonth,dyear);
  2283. *    ...
  2284. *
  2285. *   NOTES
  2286. *    It is better to use this function only from -7 to 3200!
  2287. *
  2288. *   BUGS
  2289. *    unknown.
  2290. *
  2291. *   SEE ALSO
  2292. *    GregorianDayDiff(),JulianDiffDate(),HeisDiffDate()
  2293. *
  2294. *****************************************************************************
  2295. *
  2296. *
  2297. *)
  2298.  
  2299.  VAR
  2300.     ddays    : INTEGER;
  2301.  
  2302.  BEGIN
  2303.    dday := day;
  2304.    dmonth := month;
  2305.    dyear := year;
  2306.    IF days >= 0 THEN (* add *)
  2307.      ddays := GregorianDayDiff(dday,dmonth,dyear,1,1,dyear+1);
  2308.      WHILE days >= ddays DO (* years *)
  2309.        dday := 1;
  2310.        dmonth := 1;
  2311.        INC(dyear);
  2312.        days := days - ddays;
  2313.        ddays := GregorianDayDiff(dday,dmonth,dyear,1,1,dyear+1);
  2314.      END;
  2315.      ddays := GregorianDayDiff(dday,dmonth,dyear,1,dmonth+1,dyear);
  2316.      WHILE days >= ddays DO (* months *)
  2317.        dday := 1;
  2318.        INC(dmonth);
  2319.        days := days - ddays;
  2320.        ddays := GregorianDayDiff(dday,dmonth,dyear,1,dmonth+1,dyear);
  2321.      END;
  2322.      IF days > 0 THEN (* days *)
  2323.        dday := dday + SHORTCARD(days);
  2324.      END;
  2325.    ELSE (* sub *)
  2326.      ddays := GregorianDayDiff(dday,dmonth,dyear,31,12,dyear-1);
  2327.      WHILE days <= ddays DO (* years *)
  2328.        dday := 31;
  2329.        dmonth := 12;
  2330.        DEC(dyear);
  2331.        days := days - ddays;
  2332.        ddays := GregorianDayDiff(dday,dmonth,dyear,31,12,dyear-1);
  2333.      END;
  2334.      ddays := GregorianDayDiff(dday,dmonth,dyear,GregorianMonthDays(dmonth-1,dyear),dmonth-1,dyear);
  2335.      WHILE days <= ddays DO (* months *)
  2336.        dday := GregorianMonthDays(dmonth-1,dyear);
  2337.        DEC(dmonth);
  2338.        days := days - ddays;
  2339.        ddays := GregorianDayDiff(dday,dmonth,dyear,GregorianMonthDays(dmonth-1,dyear),dmonth-1,dyear);
  2340.      END;
  2341.      IF days < 0 THEN
  2342.        dday := dday - SHORTCARD(ABS(days));
  2343.      END;
  2344.    END;
  2345.  END GregorianDiffDate;
  2346.  
  2347.  
  2348.  PROCEDURE HeisDiffDate(day,month : SHORTCARD; year,days : INTEGER;
  2349.             VAR dday,dmonth : SHORTCARD; VAR dyear : INTEGER);
  2350.  
  2351. (*
  2352. ******* Date/HeisDiffDate ***************************************************
  2353. *
  2354. *   NAME
  2355. *    HeisDiffDate -- Returns the date for a diff to another date. (V33)
  2356. *
  2357. *   SYNOPSIS
  2358. *    HeisDiffDate(day,month,year,diffdays,dday,dmonth,dyear);
  2359. *
  2360. *    PROCEDURE HeisDiffDate(day,month : SHORTCARD; year,days : INTEGER;
  2361. *         VAR dday,dmonth : SHORTCARD; VAR dyear : INTEGER);
  2362. *
  2363. *   FUNCTION
  2364. *    Returns the date wich lies diffdays before/after the specified date.
  2365. *
  2366. *   INPUTS
  2367. *    day      - day of the date
  2368. *    month    - month of the date
  2369. *    year     - year of the date
  2370. *    diffdays - difference to the date in days
  2371. *
  2372. *   RESULT
  2373. *    dday   - Destination day
  2374. *    dmonth - Destination month
  2375. *    dyear  - Destination year
  2376. *
  2377. *   EXAMPLE
  2378. *    ...
  2379. *    HeisDiffDate(23,1,1994,7,dday,dmonth,dyear);
  2380. *    ...
  2381. *
  2382. *   NOTES
  2383. *    It is better to use this function only from -7 to 8000!
  2384. *
  2385. *   BUGS
  2386. *    unknown.
  2387. *
  2388. *   SEE ALSO
  2389. *    HeisDayDiff(),JulianDiffDate(),GregorianDiffDate()
  2390. *
  2391. *****************************************************************************
  2392. *
  2393. *
  2394. *)
  2395.  
  2396.  VAR
  2397.     ddays    : INTEGER;
  2398.  
  2399.  BEGIN
  2400.    dday := day;
  2401.    dmonth := month;
  2402.    dyear := year;
  2403.    IF days >= 0 THEN (* add *)
  2404.      ddays := HeisDayDiff(dday,dmonth,dyear,1,1,dyear+1);
  2405.      WHILE days >= ddays DO (* years *)
  2406.        dday := 1;
  2407.        dmonth := 1;
  2408.        INC(dyear);
  2409.        days := days - ddays;
  2410.        ddays := HeisDayDiff(dday,dmonth,dyear,1,1,dyear+1);
  2411.      END;
  2412.      ddays := HeisDayDiff(dday,dmonth,dyear,1,dmonth+1,dyear);
  2413.      WHILE days >= ddays DO (* months *)
  2414.        dday := 1;
  2415.        INC(dmonth);
  2416.        days := days - ddays;
  2417.        ddays := HeisDayDiff(dday,dmonth,dyear,1,dmonth+1,dyear);
  2418.      END;
  2419.      IF days > 0 THEN (* days *)
  2420.        dday := dday + SHORTCARD(days);
  2421.      END;
  2422.    ELSE (* sub *)
  2423.      ddays := HeisDayDiff(dday,dmonth,dyear,31,12,dyear-1);
  2424.      WHILE days <= ddays DO (* years *)
  2425.        dday := 31;
  2426.        dmonth := 12;
  2427.        DEC(dyear);
  2428.        days := days - ddays;
  2429.        ddays := HeisDayDiff(dday,dmonth,dyear,31,12,dyear-1);
  2430.      END;
  2431.      ddays := HeisDayDiff(dday,dmonth,dyear,HeisMonthDays(dmonth-1,dyear),dmonth-1,dyear);
  2432.      WHILE days <= ddays DO (* months *)
  2433.        dday := HeisMonthDays(dmonth-1,dyear);
  2434.        DEC(dmonth);
  2435.        days := days - ddays;
  2436.        ddays := HeisDayDiff(dday,dmonth,dyear,HeisMonthDays(dmonth-1,dyear),dmonth-1,dyear);
  2437.      END;
  2438.      IF days < 0 THEN
  2439.        dday := dday - SHORTCARD(ABS(days));
  2440.      END;
  2441.    END;
  2442.  END HeisDiffDate;
  2443.  
  2444.  (* ----------------------------------------------------------------------- *)
  2445.  
  2446.  PROCEDURE JYearToScaliger(year : INTEGER) : CARDINAL;
  2447.  
  2448. (*
  2449. ******* Date/JYearToScaliger ************************************************
  2450. *
  2451. *   NAME
  2452. *    JYearToScaliger -- Returns the year as Scaliger year. (V33)
  2453. *
  2454. *   SYNOPSIS
  2455. *    syear := JYearToScaliger(year);
  2456. *
  2457. *    PROCEDURE JYearToScaliger(year : INTEGER) : CARDINAL;
  2458. *
  2459. *   FUNCTION
  2460. *    Returns the Scaliger year.
  2461. *
  2462. *   INPUTS
  2463. *    year     - Julian year
  2464. *
  2465. *   RESULT
  2466. *    syear - The Scaliger year
  2467. *
  2468. *   EXAMPLE
  2469. *    ...
  2470. *    syear := JYearToScaliger(1582);
  2471. *    ...
  2472. *
  2473. *   NOTES
  2474. *    It is better to use this function only from -7 to 1582!
  2475. *
  2476. *   BUGS
  2477. *    unknown.
  2478. *
  2479. *   SEE ALSO
  2480. *    GYearToScaliger(),HYearToScaliger()
  2481. *
  2482. *****************************************************************************
  2483. *
  2484. *
  2485. *)
  2486.  
  2487.  BEGIN
  2488.    IF (year < 0) AND (year > -4714) THEN
  2489.      RETURN(4714+year);
  2490.    ELSIF (year > 0) AND (year < 3268) THEN
  2491.      RETURN(4713+year);
  2492.    ELSE
  2493.      RETURN(0);
  2494.    END;
  2495.  END JYearToScaliger;
  2496.  
  2497.  
  2498.  PROCEDURE GYearToScaliger(year : INTEGER) : CARDINAL;
  2499.  
  2500. (*
  2501. ******* Date/GYearToScaliger ************************************************
  2502. *
  2503. *   NAME
  2504. *    GYearToScaliger -- Returns the year as Scaliger year. (V33)
  2505. *
  2506. *   SYNOPSIS
  2507. *    syear := GYearToScaliger(year);
  2508. *
  2509. *    PROCEDURE GYearToScaliger(year : INTEGER) : CARDINAL;
  2510. *
  2511. *   FUNCTION
  2512. *    Returns the Scaliger year.
  2513. *
  2514. *   INPUTS
  2515. *    year     - Gregorian year
  2516. *
  2517. *   RESULT
  2518. *    syear - The Scaliger year
  2519. *
  2520. *   EXAMPLE
  2521. *    ...
  2522. *    syear := GYearToScaliger(1994);
  2523. *    ...
  2524. *
  2525. *   NOTES
  2526. *    It is better to use this function only from -7 to 3200!
  2527. *
  2528. *   BUGS
  2529. *    unknown.
  2530. *
  2531. *   SEE ALSO
  2532. *    JYearToScaliger(),HYearToScaliger()
  2533. *
  2534. *****************************************************************************
  2535. *
  2536. *
  2537. *)
  2538.  
  2539.  BEGIN
  2540.    (* if other calcs are better use here! *)
  2541.    RETURN(JYearToScaliger(year));
  2542.  END GYearToScaliger;
  2543.  
  2544.  
  2545.  PROCEDURE HYearToScaliger(year : INTEGER) : CARDINAL;
  2546.  
  2547. (*
  2548. ******* Date/HYearToScaliger ************************************************
  2549. *
  2550. *   NAME
  2551. *    HYearToScaliger -- Returns the year as Scaliger year. (V33)
  2552. *
  2553. *   SYNOPSIS
  2554. *    syear := HYearToScaliger(year);
  2555. *
  2556. *    PROCEDURE HYearToScaliger(year : INTEGER) : CARDINAL;
  2557. *
  2558. *   FUNCTION
  2559. *    Returns the Scaliger year.
  2560. *
  2561. *   INPUTS
  2562. *    year     - Heis year
  2563. *
  2564. *   RESULT
  2565. *    syear - The Scaliger year
  2566. *
  2567. *   EXAMPLE
  2568. *    ...
  2569. *    syear := HYearToScaliger(1994);
  2570. *    ...
  2571. *
  2572. *   NOTES
  2573. *    It is better to use this function only from -7 to 8000!
  2574. *
  2575. *   BUGS
  2576. *    The Scaliger period is defined to 3268!!!.
  2577. *
  2578. *   SEE ALSO
  2579. *    JYearToScaliger(),GYearToScliger()
  2580. *
  2581. *****************************************************************************
  2582. *
  2583. *
  2584. *)
  2585.  
  2586.  BEGIN
  2587.    (* for compatiblities if GYearToScaliger will be changed *)
  2588.    RETURN(GYearToScaliger(year));
  2589.  END HYearToScaliger;
  2590.  
  2591.  (* ----------------------------------------------------------------------- *)
  2592.  
  2593.  PROCEDURE ScaligerYearToJ(syear : CARDINAL) : INTEGER;
  2594.  
  2595. (*
  2596. ******* Date/ScaligerYearToJ ************************************************
  2597. *
  2598. *   NAME
  2599. *    ScaligerYearToJ -- Returns the Scaliger year as Julian year. (V33)
  2600. *
  2601. *   SYNOPSIS
  2602. *    year := ScaligerYearToJ(syear);
  2603. *
  2604. *    PROCEDURE ScaligerYearToJ(syear : CARDINAL) : INTEGER;
  2605. *
  2606. *   FUNCTION
  2607. *    Returns the Julian year of a Scaliger year.
  2608. *
  2609. *   INPUTS
  2610. *    syear     - Scaliger year
  2611. *
  2612. *   RESULT
  2613. *    year - The Julian year
  2614. *
  2615. *   EXAMPLE
  2616. *    ...
  2617. *    year := ScaligerYearToJ(4800);
  2618. *    ...
  2619. *
  2620. *   NOTES
  2621. *    It is better to use this function only from 4707 to 6295!
  2622. *
  2623. *   BUGS
  2624. *    unknown.
  2625. *
  2626. *   SEE ALSO
  2627. *    ScaligerYearToG(),ScaligerYearToH()
  2628. *
  2629. *****************************************************************************
  2630. *
  2631. *
  2632. *)
  2633.  
  2634.  BEGIN
  2635.    IF (syear < 4714) THEN
  2636.      RETURN(4714+syear);
  2637.    ELSE
  2638.      RETURN(syear-4713);
  2639.    END;
  2640.  END ScaligerYearToJ;
  2641.  
  2642.  
  2643.  PROCEDURE ScaligerYearToG(syear : CARDINAL) : INTEGER;
  2644.  
  2645. (*
  2646. ******* Date/ScaligerYearToG ************************************************
  2647. *
  2648. *   NAME
  2649. *    ScaligerYearToG -- Returns the Scaliger year as Gregorian year. (V33)
  2650. *
  2651. *   SYNOPSIS
  2652. *    year := ScaligerYearToG(syear);
  2653. *
  2654. *    PROCEDURE ScaligerYearToG(syear : CARDINAL) : INTEGER;
  2655. *
  2656. *   FUNCTION
  2657. *    Returns the Gregorian year of a Scaliger year.
  2658. *
  2659. *   INPUTS
  2660. *    syear     - Scaliger year
  2661. *
  2662. *   RESULT
  2663. *    year - The Gregorian year
  2664. *
  2665. *   EXAMPLE
  2666. *    ...
  2667. *    year := ScaligerYearToG(6400);
  2668. *    ...
  2669. *
  2670. *   NOTES
  2671. *    It is better to use this function only from 4707 to 7981!
  2672. *
  2673. *   BUGS
  2674. *    unknown.
  2675. *
  2676. *   SEE ALSO
  2677. *    ScaligerYearToJ(),ScaligerYearToH()
  2678. *
  2679. *****************************************************************************
  2680. *
  2681. *
  2682. *)
  2683.  
  2684.  BEGIN
  2685.    RETURN(ScaligerYearToJ(syear));
  2686.  END ScaligerYearToG;
  2687.  
  2688.  
  2689.  PROCEDURE ScaligerYearToH(syear : CARDINAL) : INTEGER;
  2690.  
  2691. (*
  2692. ******* Date/ScaligerYearToH ************************************************
  2693. *
  2694. *   NAME
  2695. *    ScaligerYearToH -- Returns the Scaliger year as Heis year. (V33)
  2696. *
  2697. *   SYNOPSIS
  2698. *    year := ScaligerYearToH(syear);
  2699. *
  2700. *    PROCEDURE ScaligerYearToH(syear : CARDINAL) : INTEGER;
  2701. *
  2702. *   FUNCTION
  2703. *    Returns the Heis year of a Scaliger year.
  2704. *
  2705. *   INPUTS
  2706. *    syear     - Scaliger year
  2707. *
  2708. *   RESULT
  2709. *    year - The Heis year
  2710. *
  2711. *   EXAMPLE
  2712. *    ...
  2713. *    year := ScaligerYearToH(7000);
  2714. *    ...
  2715. *
  2716. *   NOTES
  2717. *    It is better to use this function only from 4707 to 7981!
  2718. *
  2719. *   BUGS
  2720. *    unknown.
  2721. *
  2722. *   SEE ALSO
  2723. *    ScaligerYearToJ(),ScaligerYearToG()
  2724. *
  2725. *****************************************************************************
  2726. *
  2727. *
  2728. *)
  2729.  
  2730.  VAR
  2731.     year    : INTEGER;
  2732.  
  2733.  BEGIN (* for compatibilitie if ScaligerYearToG is changed! *)
  2734.    RETURN(ScaligerYearToG(syear));
  2735.  END ScaligerYearToH;
  2736.  
  2737.  (* ----------------------------------------------------------------------- *)
  2738.  
  2739.  PROCEDURE JSYearToJD(syear : CARDINAL) : LONGCARD;
  2740.  
  2741. (*
  2742. ******* Date/JSYearToJD *****************************************************
  2743. *
  2744. *   NAME
  2745. *    JSYearToJD -- Calcs the JD from a Scaliger year. (V33)
  2746. *
  2747. *   SYNOPSIS
  2748. *    jd := JSYearToJD(syear);
  2749. *
  2750. *    PROCEDURE JSYearToJD(syear : CARDINAL) : LONGCARD;
  2751. *
  2752. *   FUNCTION
  2753. *    Returns the Julianday of a Scaliger year.
  2754. *
  2755. *   INPUTS
  2756. *    syear     - Scaliger year
  2757. *
  2758. *   RESULT
  2759. *    jd - The Julianday
  2760. *
  2761. *   EXAMPLE
  2762. *    ...
  2763. *    jd := JSYearToJD(4800);
  2764. *    ...
  2765. *
  2766. *   NOTES
  2767. *    It is better to use this function only from 4707 to 6295!
  2768. *
  2769. *   BUGS
  2770. *    unknown.
  2771. *
  2772. *   SEE ALSO
  2773. *    GSYearToJD(),HSYearToJD()
  2774. *
  2775. *****************************************************************************
  2776. *
  2777. *
  2778. *)
  2779.  
  2780.  BEGIN
  2781.    RETURN((LONGCARD(syear)-1)*365+(LONGCARD(syear)+2) DIV 4);
  2782.  END JSYearToJD;
  2783.  
  2784.  
  2785.  PROCEDURE GSYearToJD(syear : CARDINAL) : LONGCARD;
  2786.  
  2787. (*
  2788. ******* Date/GSYearToJD *****************************************************
  2789. *
  2790. *   NAME
  2791. *    GSYearToJD -- Calcs the JD from a Scaliger year. (V33)
  2792. *
  2793. *   SYNOPSIS
  2794. *    jd := GSYearToJD(syear);
  2795. *
  2796. *    PROCEDURE GSYearToJD(syear : CARDINAL) : LONGCARD;
  2797. *
  2798. *   FUNCTION
  2799. *    Returns the Julianday of a Scaliger year.
  2800. *
  2801. *   INPUTS
  2802. *    syear     - Scaliger year
  2803. *
  2804. *   RESULT
  2805. *    jd - The Julianday
  2806. *
  2807. *   EXAMPLE
  2808. *    ...
  2809. *    jd := GSYearToJD(4800);
  2810. *    ...
  2811. *
  2812. *   NOTES
  2813. *    It is better to use this function only from 4707 to 7981!
  2814. *
  2815. *   BUGS
  2816. *    unknown.
  2817. *
  2818. *   SEE ALSO
  2819. *    JSYearToJD(),HSYearToJD(),GregorianDayDiff(),ScaligerYearToG()
  2820. *
  2821. *****************************************************************************
  2822. *
  2823. *
  2824. *)
  2825.  
  2826.  BEGIN
  2827.    IF syear < 6296 THEN (* 1583 *)
  2828.      RETURN(JSYearToJD(syear));
  2829.    ELSE
  2830.      RETURN(JSYearToJD(6296)-10+LONGCARD(GregorianDayDiff(1,1,1583,1,1,ScaligerYearToG(syear))));
  2831.    END;
  2832.  END GSYearToJD;
  2833.  
  2834.  
  2835.  PROCEDURE HSYearToJD(syear : CARDINAL) : LONGCARD;
  2836.  
  2837. (*
  2838. ******* Date/HSYearToJD *****************************************************
  2839. *
  2840. *   NAME
  2841. *    HSYearToJD -- Calcs the JD from a Scaliger year. (V33)
  2842. *
  2843. *   SYNOPSIS
  2844. *    jd := HSYearToJD(syear);
  2845. *
  2846. *    PROCEDURE HSYearToJD(syear : CARDINAL) : LONGCARD;
  2847. *
  2848. *   FUNCTION
  2849. *    Returns the Julianday of a Scaliger year.
  2850. *
  2851. *   INPUTS
  2852. *    syear     - Scaliger year
  2853. *
  2854. *   RESULT
  2855. *    jd - The Julianday
  2856. *
  2857. *   EXAMPLE
  2858. *    ...
  2859. *    jd := HSYearToJD(6700);
  2860. *    ...
  2861. *
  2862. *   NOTES
  2863. *    It is better to use this function only from 4707 to 7981!
  2864. *    In this version only GSYearToJD() is called, because the
  2865. *    Scaliger period is only valid to 3268
  2866. *
  2867. *   BUGS
  2868. *    unknown.
  2869. *
  2870. *   SEE ALSO
  2871. *    JSYearToJD(),GSYearToJD()
  2872. *
  2873. *****************************************************************************
  2874. *
  2875. *
  2876. *)
  2877.  
  2878.  BEGIN
  2879.    RETURN(GSYearToJD(syear));
  2880.  END HSYearToJD;
  2881.  
  2882.  (* ----------------------------------------------------------------------- *)
  2883.  
  2884.  PROCEDURE JDtoMJD(jd : LONGCARD) : LONGCARD;
  2885.  
  2886. (*
  2887. ******* Date/JDtoMJD ********************************************************
  2888. *
  2889. *   NAME
  2890. *    JDtoMJD -- Switches from JD to MJD. (V33)
  2891. *
  2892. *   SYNOPSIS
  2893. *    mjd := JDtoMJD(jd);
  2894. *
  2895. *    PROCEDURE JDtoMJD(jd : LONGCARD) : LONGCARD;
  2896. *
  2897. *   FUNCTION
  2898. *    Returns the Modified Julianday of a Julianday.
  2899. *
  2900. *   INPUTS
  2901. *    jd - Julianday
  2902. *
  2903. *   RESULT
  2904. *    mjd - The Modified Julianday
  2905. *
  2906. *   EXAMPLE
  2907. *    ...
  2908. *    mjd := JDtoMJD(2449354);
  2909. *    ...
  2910. *
  2911. *   NOTES
  2912. *    none
  2913. *
  2914. *   BUGS
  2915. *    Only use this function for jd > 2400001, because mjd is only
  2916. *    defined for this, otherwise system will crash!
  2917. *
  2918. *   SEE ALSO
  2919. *    MJDtoJD()
  2920. *
  2921. *****************************************************************************
  2922. *
  2923. *
  2924. *)
  2925.  
  2926.  BEGIN
  2927.    RETURN(jd-2400001);
  2928.  END JDtoMJD;
  2929.  
  2930.  
  2931.  PROCEDURE MJDtoJD(mjd : LONGCARD) : LONGCARD;
  2932.  
  2933. (*
  2934. ******* Date/MJDtoJD ********************************************************
  2935. *
  2936. *   NAME
  2937. *    MJDtoJD -- Switches from MJD to JD. (V33)
  2938. *
  2939. *   SYNOPSIS
  2940. *    jd := MJDtoJD(mjd);
  2941. *
  2942. *    PROCEDURE MJDtoJD(mjd : LONGCARD) : LONGCARD;
  2943. *
  2944. *   FUNCTION
  2945. *    Returns the Julianday of a Modified Julianday.
  2946. *
  2947. *   INPUTS
  2948. *    mjd - Modified Julianday
  2949. *
  2950. *   RESULT
  2951. *    jd - The Julianday
  2952. *
  2953. *   EXAMPLE
  2954. *    ...
  2955. *    jd := JDtoMJD(49353);
  2956. *    ...
  2957. *
  2958. *   NOTES
  2959. *    none
  2960. *
  2961. *   BUGS
  2962. *    unknown.
  2963. *
  2964. *   SEE ALSO
  2965. *    MJDtoJD()
  2966. *
  2967. *****************************************************************************
  2968. *
  2969. *
  2970. *)
  2971.  
  2972.  BEGIN
  2973.    RETURN(mjd+2400001);
  2974.  END MJDtoJD;
  2975.  
  2976.  (* ----------------------------------------------------------------------- *)
  2977.  
  2978.  PROCEDURE JulianToJD(day,month : SHORTCARD; year : INTEGER) : LONGCARD;
  2979.  
  2980. (*
  2981. ******* Date/JulianToJD *****************************************************
  2982. *
  2983. *   NAME
  2984. *    JulianToJD -- Returns the JD for a date. (V33)
  2985. *
  2986. *   SYNOPSIS
  2987. *    jd := JulianToJD(day,month,year);
  2988. *
  2989. *    PROCEDURE JulianToJD(day,month : SHORTCARD;
  2990. *        year : INTEGER) : LONGCARD;
  2991. *
  2992. *   FUNCTION
  2993. *    Returns the JD for a Julian date.
  2994. *
  2995. *   INPUTS
  2996. *    day      - day of the date to convert
  2997. *    month    - month of the date to convert
  2998. *    year     - year of the date to convert
  2999. *
  3000. *   RESULT
  3001. *    jd - This is the JD
  3002. *
  3003. *   EXAMPLE
  3004. *    ...
  3005. *    jd := JulianToJD(23,1,1994);
  3006. *    ...
  3007. *
  3008. *   NOTES
  3009. *    It is better to use this function only from -7 to 1582!
  3010. *
  3011. *   BUGS
  3012. *    unknown.
  3013. *
  3014. *   SEE ALSO
  3015. *    GregorianToJD(),HeisToJD(),JSYearToJD(),JYearToScaliger(),
  3016. *    JulianDayDiff()
  3017. *
  3018. *****************************************************************************
  3019. *
  3020. *
  3021. *)
  3022.  
  3023.  BEGIN
  3024.    RETURN(JSYearToJD(JYearToScaliger(year))+LONGCARD(JulianDayDiff(1,1,year,day,month,year)));
  3025.  END JulianToJD;
  3026.  
  3027.  
  3028.  PROCEDURE GregorianToJD(day,month : SHORTCARD; year : INTEGER) : LONGCARD;
  3029.  
  3030. (*
  3031. ******* Date/GregorianToJD **************************************************
  3032. *
  3033. *   NAME
  3034. *    GregorianToJD -- Returns the JD for a date. (V33)
  3035. *
  3036. *   SYNOPSIS
  3037. *    jd := GregorianToJD(day,month,year);
  3038. *
  3039. *    PROCEDURE GregorianToJD(day,month : SHORTCARD;
  3040. *        year : INTEGER) : LONGCARD;
  3041. *
  3042. *   FUNCTION
  3043. *    Returns the JD for a Gregorian date.
  3044. *
  3045. *   INPUTS
  3046. *    day      - day of the date to convert
  3047. *    month    - month of the date to convert
  3048. *    year     - year of the date to convert
  3049. *
  3050. *   RESULT
  3051. *    jd - This is the JD
  3052. *
  3053. *   EXAMPLE
  3054. *    ...
  3055. *    jd := GregorianToJD(23,1,1994);
  3056. *    ...
  3057. *
  3058. *   NOTES
  3059. *    It is better to use this function only from -7 to 3200!
  3060. *
  3061. *   BUGS
  3062. *    unknown.
  3063. *
  3064. *   SEE ALSO
  3065. *    JulianToJD(),HeisToJD(),GSYearToJD(),GYearToScaliger(),
  3066. *    GregorianDayDiff()
  3067. *
  3068. *****************************************************************************
  3069. *
  3070. *
  3071. *)
  3072.  
  3073.  BEGIN
  3074.    RETURN(GSYearToJD(GYearToScaliger(year))+LONGCARD(GregorianDayDiff(1,1,year,day,month,year)));
  3075.  END GregorianToJD;
  3076.  
  3077.  
  3078.  PROCEDURE HeisToJD(day,month : SHORTCARD; year : INTEGER) : LONGCARD;
  3079.  
  3080. (*
  3081. ******* Date/HeisToJD *******************************************************
  3082. *
  3083. *   NAME
  3084. *    HeisToJD -- Returns the JD for a date. (V33)
  3085. *
  3086. *   SYNOPSIS
  3087. *    jd := HeisToJD(day,month,year);
  3088. *
  3089. *    PROCEDURE HeisToJD(day,month : SHORTCARD;
  3090. *        year : INTEGER) : LONGCARD;
  3091. *
  3092. *   FUNCTION
  3093. *    Returns the JD for a Heis date.
  3094. *
  3095. *   INPUTS
  3096. *    day      - day of the date to convert
  3097. *    month    - month of the date to convert
  3098. *    year     - year of the date to convert
  3099. *
  3100. *   RESULT
  3101. *    jd - This is the JD
  3102. *
  3103. *   EXAMPLE
  3104. *    ...
  3105. *    jd := HeisToJD(23,1,1994);
  3106. *    ...
  3107. *
  3108. *   NOTES
  3109. *    It is better to use this function only from -7 to 3268!
  3110. *
  3111. *   BUGS
  3112. *    unknown.
  3113. *
  3114. *   SEE ALSO
  3115. *    JulianToJD(),GregorianToJD(),HSYearToJD(),HYearToScaliger(),
  3116. *    HeisDayDiff()
  3117. *
  3118. *****************************************************************************
  3119. *
  3120. *
  3121. *)
  3122.  
  3123.  BEGIN
  3124.    RETURN(HSYearToJD(HYearToScaliger(year))+LONGCARD(HeisDayDiff(1,1,year,day,month,year)));
  3125.  END HeisToJD;
  3126.  
  3127.  (* ----------------------------------------------------------------------- *)
  3128.  
  3129.  PROCEDURE TimeToJD(hour,min,sec : SHORTCARD) : REAL;
  3130.  
  3131. (*
  3132. ******* Date/TimeToJD *******************************************************
  3133. *
  3134. *   NAME
  3135. *    TimeToJD -- Returns the JD for a time. (V33)
  3136. *
  3137. *   SYNOPSIS
  3138. *    jd := TimeToJD(hour,min,sec);
  3139. *
  3140. *    PROCEDURE TimeToJD(hour,min,sec : SHORTCARD) : REAL;
  3141. *
  3142. *   FUNCTION
  3143. *    Returns the JD for a specified time.
  3144. *
  3145. *   INPUTS
  3146. *    hour - hour of the time to convert
  3147. *    min  - minute of the time to convert
  3148. *    sec  - sec. of the time to convert
  3149. *
  3150. *   RESULT
  3151. *    jd - This is the JD time
  3152. *
  3153. *   EXAMPLE
  3154. *    ...
  3155. *    jd := TimeToJD(16,33,0);
  3156. *    ...
  3157. *
  3158. *   NOTES
  3159. *    none
  3160. *
  3161. *   BUGS
  3162. *    There is no check, if the specified time is a valid time!
  3163. *
  3164. *   SEE ALSO
  3165. *    JDToTime()
  3166. *
  3167. *****************************************************************************
  3168. *
  3169. *
  3170. *)
  3171.  
  3172.  BEGIN
  3173.    RETURN(REAL(LONGCARD(hour)*3600+CARDINAL(min)*60+sec) / 86400.0);
  3174.  END TimeToJD;
  3175.  
  3176.  
  3177.  PROCEDURE JDToTime(jd : REAL; VAR rhour,rmin,rsec : SHORTCARD);
  3178.  
  3179. (*
  3180. ******* Date/JDToTime *******************************************************
  3181. *
  3182. *   NAME
  3183. *    JDToTime -- Returns the real time for a JD time. (V33)
  3184. *
  3185. *   SYNOPSIS
  3186. *    JDToTime(jd,rhour,rmin,rsec);
  3187. *
  3188. *    PROCEDURE JDToTime(jd : REAL; VAR rhour,rmin,rsec : SHORTCARD);
  3189. *
  3190. *   FUNCTION
  3191. *    Returns the real time for a JD time.
  3192. *
  3193. *   INPUTS
  3194. *    jd - JD time
  3195. *
  3196. *   RESULT
  3197. *    rhour - 24 hour real time
  3198. *    rmin  - real minutes
  3199. *    rsec  - real seconds
  3200. *
  3201. *   EXAMPLE
  3202. *    ...
  3203. *    JDToTime(0.76543,rhour,rmin,rsec);
  3204. *    ...
  3205. *
  3206. *   NOTES
  3207. *    none.
  3208. *
  3209. *   BUGS
  3210. *    If jd is > 0 (including days) there will be occur arithmetic bugs!
  3211. *
  3212. *   SEE ALSO
  3213. *    TimeToJD()
  3214. *
  3215. *****************************************************************************
  3216. *
  3217. *
  3218. *)
  3219.  
  3220.  VAR
  3221.     sec    : LONGCARD;
  3222.  
  3223.  BEGIN
  3224.      IF jd > 0.0 THEN
  3225.        jd := jd - REAL(LONGCARD(jd));
  3226.      END;
  3227.      sec := LONGCARD(jd * 86400.0);
  3228.      rhour := sec DIV 3600;
  3229.      sec := sec - (sec DIV 3600) * 3600;
  3230.      rmin := sec DIV 60;
  3231.      sec := sec - (sec DIV 60) * 60;
  3232.      rsec := sec;
  3233.  END JDToTime;
  3234.  
  3235.  (* ----internal----------------------------------------------------------- *)
  3236.  
  3237.  PROCEDURE GregorianSZ(year : CARDINAL) : SHORTCARD;
  3238.  
  3239. (*
  3240. *****i* Date/GregorianSZ ****************************************************
  3241. *
  3242. *   NAME
  3243. *    GregorianSZ -- Returns the 'Sonnenzirkel' (V33)
  3244. *
  3245. *   SYNOPSIS
  3246. *    sz := GregorianSZ(year);
  3247. *
  3248. *    PROCEDURE GregorianSZ(year : CARDINAL) : SHORTCARD;
  3249. *
  3250. *   FUNCTION
  3251. *    Returns the 'Sonnenzirkel' of a year.
  3252. *
  3253. *   INPUTS
  3254. *    year     - For this year the 'Sonnenzirkel' is calculatet.
  3255. *
  3256. *   RESULT
  3257. *    sz - The 'Sonnenzirkel' for the specified year.
  3258. *
  3259. *   EXAMPLE
  3260. *    ...
  3261. *    sz := GregorianSZ(1994);
  3262. *    ...
  3263. *
  3264. *   NOTES
  3265. *    Use this only for 1582 to 4100!
  3266. *
  3267. *   BUGS
  3268. *    unknown.
  3269. *
  3270. *   SEE ALSO
  3271. *    GYearToScaliger()
  3272. *
  3273. *****************************************************************************
  3274. *
  3275. *
  3276. *)
  3277.  
  3278.  VAR
  3279.     gz    : SHORTCARD;
  3280.  
  3281.  BEGIN
  3282.    gz := GYearToScaliger(year) MOD 28;
  3283.    IF gz = 0 THEN
  3284.      gz := 28;
  3285.    END;
  3286.    RETURN(gz);
  3287.  END GregorianSZ;
  3288.  
  3289.  
  3290.  PROCEDURE GregorianGZ(year : CARDINAL) : SHORTCARD;
  3291.  
  3292. (*
  3293. *****i* Date/GregorianGZ ****************************************************
  3294. *
  3295. *   NAME
  3296. *    GregorianGZ -- Returns the 'Goldene Zahl' (golden number) (V33)
  3297. *
  3298. *   SYNOPSIS
  3299. *    gz := GregorianGZ(year);
  3300. *
  3301. *    PROCEDURE GregorianGZ(year : CARDINAL) : SHORTCARD;
  3302. *
  3303. *   FUNCTION
  3304. *    Returns the 'Goldene Zahl' of a year.
  3305. *
  3306. *   INPUTS
  3307. *    year     - For this year the 'Goldene Zahl' is calculatet.
  3308. *
  3309. *   RESULT
  3310. *    gz - The 'Goldene Zahl' for the specified year.
  3311. *
  3312. *   EXAMPLE
  3313. *    ...
  3314. *    gz := GregorianGZ(1994);
  3315. *    ...
  3316. *
  3317. *   NOTES
  3318. *    Use this only for 1582 to 4100!
  3319. *
  3320. *   BUGS
  3321. *    unknown.
  3322. *
  3323. *   SEE ALSO
  3324. *    GYearToScaliger()
  3325. *
  3326. *****************************************************************************
  3327. *
  3328. *
  3329. *)
  3330.  
  3331.  VAR
  3332.     syear    : CARDINAL;
  3333.  
  3334.  BEGIN
  3335.    syear := GYearToScaliger(year) MOD 19;
  3336.    IF syear = 0 THEN
  3337.      syear := 19;
  3338.    END;
  3339.    RETURN(syear);
  3340.  END GregorianGZ;
  3341.  
  3342.  
  3343.    PROCEDURE GEP(year : CARDINAL) : SHORTCARD;
  3344.  
  3345. (*
  3346. *****i* Date/GEP ************************************************************
  3347. *
  3348. *   NAME
  3349. *    GEP -- Internal function to help calculating the 'EP' (V33)
  3350. *
  3351. *   SYNOPSIS
  3352. *    hep := GEP(year);
  3353. *
  3354. *    PROCEDURE GEP(year : CARDINAL) : SHORTCARD;
  3355. *
  3356. *   FUNCTION
  3357. *    Internal function to help calculating the 'EP'
  3358. *
  3359. *   INPUTS
  3360. *    year - This is the year for which the help EP is to be
  3361. *        calculatetd
  3362. *
  3363. *   RESULT
  3364. *    hep - The help value for the EP calculation.
  3365. *
  3366. *   EXAMPLE
  3367. *    ...
  3368. *    hep := GEP(1994);
  3369. *    ...
  3370. *
  3371. *   NOTES
  3372. *    Use this only for 1582 to 4100!
  3373. *
  3374. *   BUGS
  3375. *    unknown.
  3376. *
  3377. *   SEE ALSO
  3378. *
  3379. *
  3380. *****************************************************************************
  3381. *
  3382. *
  3383. *)
  3384.  
  3385.    VAR
  3386.     century,decade    : SHORTCARD;
  3387.     ep        : INTEGER;
  3388.  
  3389.    BEGIN
  3390.      ep := 1; (* 1582 *)
  3391.      century := year DIV 100;
  3392.      decade := year - century * 100;
  3393.      IF year < 1701 THEN
  3394.        RETURN(1);
  3395.      ELSIF year < 1800 THEN
  3396.        RETURN(0);
  3397.      ELSE
  3398.        ep := ep - INTEGER(((century) MOD 4) + (((century-16) DIV 4) * 3));
  3399.        IF (decade = 0) AND ((century MOD 4) > 0) THEN
  3400.          INC(ep);
  3401.        END;
  3402.        ep := ep + INTEGER((century-18) DIV 3);
  3403.        IF (((century-18) MOD 3) > 0) OR (decade > 0) THEN
  3404.          INC(ep);
  3405.        END;
  3406.        IF ep > 29 THEN
  3407.          ep := ep MOD 30;
  3408.        END;
  3409.        IF ep < 0 THEN
  3410.          ep := ep + 30;
  3411.        END;
  3412.        RETURN(SHORTCARD(ep));
  3413.      END;
  3414.    END GEP;
  3415.  
  3416.  
  3417.  PROCEDURE GregorianEP(year : CARDINAL) : SHORTCARD;
  3418.  
  3419. (*
  3420. *****i* Date/GregorianEP ****************************************************
  3421. *
  3422. *   NAME
  3423. *    GregorianEP -- Returns the 'Epakte' (V33)
  3424. *
  3425. *   SYNOPSIS
  3426. *    ep := GregorianEP(year);
  3427. *
  3428. *    PROCEDURE GregorianEP(year : CARDINAL) : SHORTCARD;
  3429. *
  3430. *   FUNCTION
  3431. *    Returns the 'Epakte' of a year.
  3432. *
  3433. *   INPUTS
  3434. *    year     - For this year the 'Epakte' is calculatet.
  3435. *
  3436. *   RESULT
  3437. *    ep - The 'Epakte' for the specified year.
  3438. *
  3439. *   EXAMPLE
  3440. *    ...
  3441. *    ep := GregorianEP(1994);
  3442. *    ...
  3443. *
  3444. *   NOTES
  3445. *    Use this only for 1582 to 4100!
  3446. *
  3447. *   BUGS
  3448. *    unknown.
  3449. *
  3450. *   SEE ALSO
  3451. *    GregorianGZ(),GEP()
  3452. *
  3453. *****************************************************************************
  3454. *
  3455. *
  3456. *)
  3457.  
  3458.  VAR
  3459.     ep    : SHORTCARD;
  3460.  
  3461.  BEGIN
  3462.    IF year >= 1582 THEN
  3463.      ep := ((GregorianGZ(year)-1)*11 + GEP(year)) MOD 30;
  3464.      IF ep = 0 THEN
  3465.        ep := 30;
  3466.      END;
  3467.      RETURN(ep);
  3468.    ELSE
  3469.      RETURN(31);
  3470.    END;
  3471.  END GregorianEP;
  3472.  
  3473.  
  3474.  PROCEDURE GregorianJHStartSB(century : SHORTCARD) : SHORTCARD;
  3475.  
  3476. (*
  3477. *****i* Date/GregorianJHStartSB *********************************************
  3478. *
  3479. *   NAME
  3480. *    GregorianJHStartSB -- Returns the 'Sonntagsbuchstabe' (V33)
  3481. *
  3482. *   SYNOPSIS
  3483. *    csb := GregorianJHStartSB(century);
  3484. *
  3485. *    PROCEDURE GregorianJHStartSB(century : SHORTCARD) : SHORTCARD;
  3486. *
  3487. *   FUNCTION
  3488. *    Returns start 'SB' for a century.
  3489. *
  3490. *   INPUTS
  3491. *    century - For this century the start 'SB' is calculatet.
  3492. *
  3493. *   RESULT
  3494. *    csb - The start 'SB' for the specified century.
  3495. *
  3496. *   EXAMPLE
  3497. *    ...
  3498. *    csb := GregorianJHStartSB(19);
  3499. *    ...
  3500. *
  3501. *   NOTES
  3502. *    Use this only for 15 to 31!
  3503. *
  3504. *   BUGS
  3505. *    unknown.
  3506. *
  3507. *   SEE ALSO
  3508. *
  3509. *
  3510. *****************************************************************************
  3511. *
  3512. *
  3513. *)
  3514.  
  3515.  VAR
  3516.     sb    : SHORTCARD;
  3517.  
  3518.  BEGIN
  3519.   IF century = 15 THEN
  3520.     RETURN(4);
  3521.   ELSE
  3522.     sb := GregorianJHStartSB(century-1);
  3523.     IF (century MOD 4) > 0 THEN
  3524.       INC(sb);
  3525.     END;
  3526.     sb := sb MOD 7;
  3527.     IF sb = 0 THEN
  3528.       sb := 7;
  3529.     END;
  3530.     RETURN(sb);
  3531.   END;
  3532.  END GregorianJHStartSB;
  3533.  
  3534.  
  3535.  PROCEDURE GregorianJHSB(year : CARDINAL) : SHORTCARD;
  3536.  
  3537. (*
  3538. *****i* Date/GregorianSB ****************************************************
  3539. *
  3540. *   NAME
  3541. *    GregorianJHSB -- Returns the 'Sonntagsbuchstabe' (V33)
  3542. *
  3543. *   SYNOPSIS
  3544. *    sb := GregorianJHSB(year);
  3545. *
  3546. *    PROCEDURE GregorianJHSB(year : CARDINAL) : SHORTCARD;
  3547. *
  3548. *   FUNCTION
  3549. *    Returns the start 'SB' for a century year.
  3550. *
  3551. *   INPUTS
  3552. *    year - For this century year the start 'SB' is calculatet.
  3553. *
  3554. *   RESULT
  3555. *    sb - The start 'SB' for the specified year.
  3556. *
  3557. *   EXAMPLE
  3558. *    ...
  3559. *    sb := GregorianJHSB(1994);
  3560. *    ...
  3561. *
  3562. *   NOTES
  3563. *    Use this only for 1583 to 3199!
  3564. *
  3565. *   BUGS
  3566. *    unknown.
  3567. *
  3568. *   SEE ALSO
  3569. *    GregorianLeapYear(),GregorianJHStartSB()
  3570. *
  3571. *****************************************************************************
  3572. *
  3573. *
  3574. *)
  3575.  
  3576.  BEGIN
  3577.   IF ((year MOD 100) = 0) AND (~GregorianLeapYear(INTEGER(year))) THEN
  3578.     RETURN(SHORTCARD(((year DIV 100) MOD 4) *2 +1));
  3579.   ELSE
  3580.     RETURN(GregorianJHStartSB(year DIV 100));
  3581.   END;
  3582.  END GregorianJHSB;
  3583.  
  3584.  
  3585.  PROCEDURE GregorianSB(year : CARDINAL) : SHORTCARD;
  3586.  
  3587. (*
  3588. *****i* Date/GregorianSB ****************************************************
  3589. *
  3590. *   NAME
  3591. *    GregorianSB -- Returns the 'Sonntagsbuchstabe' (V33)
  3592. *
  3593. *   SYNOPSIS
  3594. *    sb := GregorianSB(year);
  3595. *
  3596. *    PROCEDURE GregorianSB(year : CARDINAL) : SHORTCARD;
  3597. *
  3598. *   FUNCTION
  3599. *    Returns the 'SB' for a year.
  3600. *
  3601. *   INPUTS
  3602. *    year - For this year the 'SB' is calculatet.
  3603. *
  3604. *   RESULT
  3605. *    sb - The 'SB' for the specified year.
  3606. *        This means the day the first Sunday lies on :)
  3607. *
  3608. *   EXAMPLE
  3609. *    ...
  3610. *    sb := GregorianSB(1994);
  3611. *    ...
  3612. *
  3613. *   NOTES
  3614. *    Use this only for 1583 to 3199!
  3615. *
  3616. *   BUGS
  3617. *    unknown.
  3618. *
  3619. *   SEE ALSO
  3620. *    GregorianLeapYear(),GregorianSZ(),GregorianJHStartSB()
  3621. *
  3622. *****************************************************************************
  3623. *
  3624. *
  3625. *)
  3626.  
  3627.  VAR
  3628.     sz,csb,i    : SHORTCARD;
  3629.  
  3630.  BEGIN
  3631.    IF ((year MOD 100) = 0) AND (~GregorianLeapYear(INTEGER(year))) THEN
  3632.      RETURN(SHORTCARD(((year DIV 100) MOD 4) *2 +1));
  3633.    ELSE
  3634.      sz := GregorianSZ(year);
  3635.      csb := GregorianJHStartSB(year DIV 100);
  3636.      IF sz = 28 THEN
  3637.        RETURN(csb);
  3638.      ELSE
  3639.        FOR i := 27 TO sz BY -1 DO
  3640.          INC(csb);
  3641.          IF csb = 8 THEN
  3642.            csb := 1;
  3643.          END;
  3644.          IF ((i-1) MOD 4) = 0 THEN
  3645.            INC(csb);
  3646.            IF csb = 8 THEN
  3647.              csb := 1;
  3648.            END;
  3649.          END;
  3650.        END;
  3651.        RETURN(csb);
  3652.      END;
  3653.    END;
  3654.  END GregorianSB;
  3655.  
  3656.  (* ----------------------------------------------------------------------- *)
  3657.  
  3658.  PROCEDURE GregorianMoonAge(day,month : SHORTCARD; year : INTEGER) : SHORTCARD;
  3659.  
  3660. (*
  3661. ******* Date/GregorianMoonAge ***********************************************
  3662. *
  3663. *   NAME
  3664. *    GregorianMoonAge -- Returns the age of the moon (V33)
  3665. *
  3666. *   SYNOPSIS
  3667. *    ep := GregorianMoonAge(day,month,year);
  3668. *
  3669. *    PROCEDURE GregorianMoonAge(day,month : SHORTCARD;
  3670. *        year : CARDINAL) : SHORTCARD;
  3671. *
  3672. *   FUNCTION
  3673. *    Returns the age of the moon on a specified date.
  3674. *
  3675. *   INPUTS
  3676. *    day   - For this day the age is calculated.
  3677. *    month - For this month the age is calculated.
  3678. *    year  - For this year the age is calculated.
  3679. *
  3680. *   RESULT
  3681. *    ep - The age of the moon on the specified date.
  3682. *
  3683. *   EXAMPLE
  3684. *    ...
  3685. *    ep := GregorianMoonAge(18,9,1994);
  3686. *    ...
  3687. *
  3688. *   NOTES
  3689. *    Use this only for 1582 to 4100!
  3690. *    This is only a experimental version!
  3691. *
  3692. *   BUGS
  3693. *    unknown.
  3694. *
  3695. *   SEE ALSO
  3696. *    MoonMonthAge(),GregorianEP()
  3697. *
  3698. *****************************************************************************
  3699. *
  3700. *
  3701. *)
  3702.  
  3703.    PROCEDURE MoonMonthAge(month,ep : SHORTCARD) : SHORTCARD;
  3704.  
  3705. (*
  3706. *****i* Date/MoonMonthAge ***************************************************
  3707. *
  3708. *   NAME
  3709. *    MoonMonthAge -- Calculates the age of the moon on month start (V33)
  3710. *
  3711. *   SYNOPSIS
  3712. *    ep := MoonMonthAge(month,ep);
  3713. *
  3714. *    PROCEDURE MoonMonthAge(month,ep : SHORTCARD) : SHORTCARD;
  3715. *
  3716. *   FUNCTION
  3717. *    Returns the age of the moon on the start of a month.
  3718. *
  3719. *   INPUTS
  3720. *    month - Month for which the moonage is needed.
  3721. *    ep    - 'Epakte' of the newyears-day.
  3722. *
  3723. *   RESULT
  3724. *    ep - The moonage on the 1. of the specified month.
  3725. *
  3726. *   EXAMPLE
  3727. *    ...
  3728. *    ep := MoonMonthAge(2,17); (* 17 is for 1994 *)
  3729. *    ...
  3730. *
  3731. *   NOTES
  3732. *    This is only a experimental version!
  3733. *
  3734. *   BUGS
  3735. *    unknown.
  3736. *
  3737. *   SEE ALSO
  3738. *    GregorianMonthDays()
  3739. *
  3740. *****************************************************************************
  3741. *
  3742. *
  3743. *)
  3744.  
  3745.    BEGIN
  3746.      IF month = 1 THEN
  3747.        RETURN(ep);
  3748.      ELSE
  3749.        IF month MOD 2 = 0 THEN
  3750.          ep := (MoonMonthAge(month-1,ep) + GregorianMonthDays(month-1,year)) MOD 29;
  3751.        ELSE
  3752.          ep := (MoonMonthAge(month-1,ep) + GregorianMonthDays(month-1,year)) MOD 30;
  3753.        END;
  3754.        RETURN(ep);
  3755.      END;
  3756.    END MoonMonthAge;
  3757.  
  3758.  VAR
  3759.     ep    : SHORTCARD;
  3760.  
  3761.  BEGIN
  3762.    ep := GregorianEP(year);
  3763.    ep := MoonMonthAge(month,ep);
  3764.    ep := ep + day -1;
  3765.    IF month > 1 THEN
  3766.      IF month MOD 2 = 0 THEN
  3767.        ep := ep MOD 30;
  3768.        IF ep = 0 THEN
  3769.          ep := 30;
  3770.        END;
  3771.      ELSE
  3772.        ep := ep MOD 29;
  3773.        IF ep = 0 THEN
  3774.          ep := 29;
  3775.        END;
  3776.      END;
  3777.    ELSE
  3778.      IF ep > 29 THEN
  3779.        ep := ep MOD 29;
  3780.      END;
  3781.    END;
  3782.    RETURN(ep);
  3783.  END GregorianMoonAge;
  3784.  
  3785.  (* ----------------------------------------------------------------------- *)
  3786. (*
  3787.  PROCEDURE GregorianEasterOld(year : INTEGER; VAR dday,dmonth : SHORTCARD);
  3788.  
  3789. (*
  3790. *****i* Date/GregorianEaster ************************************************
  3791. *
  3792. *   NAME
  3793. *    GregorianEaster -- Returns the date of eastern in a year (V33)
  3794. *
  3795. *   SYNOPSIS
  3796. *    GregorianEaster(year,dday,dmonth);
  3797. *
  3798. *    PROCEDURE GregorianEaster(year : INTEGER;
  3799. *        VAR dday,dmonth : SHORTCARD);
  3800. *
  3801. *   FUNCTION
  3802. *    Returns the date of eastern for a specified year.
  3803. *
  3804. *   INPUTS
  3805. *    year  - eastern is calculated for this year
  3806. *
  3807. *   RESULT
  3808. *    dday   - day of easter-Sunday
  3809. *    dmonth - month of easter-Sunday
  3810. *
  3811. *   EXAMPLE
  3812. *    ...
  3813. *    GregorianEaster(1994,dday,dmonth);
  3814. *    ...
  3815. *
  3816. *   NOTES
  3817. *    Use this only for 1582 to 4100!
  3818. *    This is only a experimental version!
  3819. *
  3820. *   BUGS
  3821. *    In some years eastern lies one week behind!
  3822. *
  3823. *   SEE ALSO
  3824. *    GregorianMoonAge(),GregorianDaysAfterWeekday()
  3825. *
  3826. *****************************************************************************
  3827. *
  3828. *
  3829. *)
  3830.  
  3831.  VAR
  3832.     ep    : SHORTCARD;
  3833.  
  3834.  BEGIN
  3835.    dday := 21;
  3836.    dmonth := 3;
  3837.    ep := GregorianMoonAge(21,3,year);
  3838.    IF ep < 14 THEN
  3839.      dday := dday + (14-ep);
  3840.    ELSE
  3841.      dday := dday + (29-ep) + 13;
  3842.    END;
  3843.    IF dday > 31 THEN
  3844.      dday := dday - 31;
  3845.      INC(dmonth);
  3846.    END;
  3847.    dday := dday + GregorianDaysAfterWeekday(dday,dmonth,year,Sunday);
  3848.    IF dday > 31 THEN
  3849.      dday := dday - 31;
  3850.      INC(dmonth);
  3851.    END;
  3852.  END GregorianEasterOld;
  3853. *)
  3854.  
  3855.  PROCEDURE GregorianEaster(year : INTEGER; VAR dday,dmonth : SHORTCARD);
  3856.  
  3857. (*
  3858. ******* Date/GregorianEaster ************************************************
  3859. *
  3860. *   NAME
  3861. *    GregorianEaster -- Returns the date of eastern in a year (V33)
  3862. *
  3863. *   SYNOPSIS
  3864. *    GregorianEaster(year,dday,dmonth);
  3865. *
  3866. *    PROCEDURE GregorianEaster(year : INTEGER;
  3867. *        VAR dday,dmonth : SHORTCARD);
  3868. *
  3869. *   FUNCTION
  3870. *    Returns the date of eastern for a specified year.
  3871. *
  3872. *   INPUTS
  3873. *    year  - eastern is calculated for this year
  3874. *
  3875. *   RESULT
  3876. *    dday   - day of easter-Sunday
  3877. *    dmonth - month of easter-Sunday
  3878. *
  3879. *   EXAMPLE
  3880. *    ...
  3881. *    GregorianEaster(1994,dday,dmonth);
  3882. *    ...
  3883. *
  3884. *   NOTES
  3885. *    Use this only for 1900 to 2099!
  3886. *    Tested for 1977-1994! But this formula is from Gauß - so it must be
  3887. *    correct :)
  3888. *
  3889. *   BUGS
  3890. *    None.
  3891. *
  3892. *   SEE ALSO
  3893. *    GEP(),GregorianJHSB()
  3894. *
  3895. *****************************************************************************
  3896. *
  3897. *
  3898. *)
  3899.  
  3900.  VAR
  3901.      a,d,e,f    : SHORTCARD;
  3902.      M,N    : SHORTINT;
  3903.  
  3904.  BEGIN
  3905.    M := SHORTINT(30 - GEP(year)) - 7;
  3906.    IF M < 0 THEN
  3907.      M := M + 30;
  3908.    END;
  3909.    N := GregorianJHSB(year)-2;
  3910.    IF N < 1 THEN
  3911.      N := N + 7;
  3912.    END;
  3913.    a := SHORTCARD(year MOD 19);
  3914.    d := SHORTCARD((19*CARDINAL(a)+SHORTCARD(M)) MOD 30);
  3915.    e := SHORTCARD((2*CARDINAL(year MOD 4)+4*CARDINAL(year MOD 7)+6*CARDINAL(d)+SHORTCARD(N)) MOD 7);
  3916.    f := d+e;
  3917.    IF f < 10 THEN (* märz *)
  3918.      dmonth := 3;
  3919.      dday := 22+f;
  3920.    ELSE (* april *)
  3921.      dmonth := 4;
  3922.      dday := f-9;
  3923.      IF dday=26 THEN
  3924.        dday := 19;
  3925.      ELSIF (dday=25) AND (d=28) AND (a>10) THEN
  3926.        dday := 18;
  3927.      END;
  3928.    END;
  3929.  END GregorianEaster;
  3930.  
  3931.  (* ----------------------------------------------------------------------- *)
  3932.  
  3933.  PROCEDURE TimeZoneFactor(degree : SHORTINT) : SHORTINT;
  3934.  
  3935. (*
  3936. ******* Date/TimeZoneFactor *************************************************
  3937. *
  3938. *   NAME
  3939. *    TimeZoneFactor -- Returns the value you have to add to GMT time (V33)
  3940. *
  3941. *   SYNOPSIS
  3942. *    addhours := TimeZoneFactor(degrees);
  3943. *
  3944. *    PROCEDURE TimeZoneFactor(degree : SHORTINT) : SHORTINT;
  3945. *
  3946. *   FUNCTION
  3947. *    This gives you the hours you have to add to GMT time,
  3948. *    specified on the fact, that a timezone is 15 degrees
  3949. *    and that GMT is centered on 0 degrees!
  3950. *
  3951. *   INPUTS
  3952. *    degrees - Position of timezone you live in (from -180 to +180)
  3953. *
  3954. *   RESULT
  3955. *    addhours - Time to add to GMT time to get your locale zone time
  3956. *        (-12 to +12)
  3957. *
  3958. *   EXAMPLE
  3959. *    ...
  3960. *    addhours := TimeZoneFactor(-8);
  3961. *    ...
  3962. *
  3963. *   NOTES
  3964. *    none
  3965. *
  3966. *   BUGS
  3967. *    No errorcheck, if you put in valid degrees (-180 to +180).
  3968. *    Only full degrees are supportet, keep sure that you
  3969. *    round in the right way for 0.x degree places
  3970. *    I am not sure about the correct +/- behaviour!!!
  3971. *
  3972. *   SEE ALSO
  3973. *
  3974. *
  3975. *****************************************************************************
  3976. *
  3977. *
  3978. *)
  3979.  
  3980.  BEGIN
  3981.    IF degree >= 0 THEN
  3982.      RETURN(SHORTINT(REAL(degree) / 15.0 + 0.5));
  3983.    ELSE
  3984.      RETURN(SHORTINT(REAL(degree) / 15.0 - 0.5));
  3985.    END;
  3986.  END TimeZoneFactor;
  3987.  
  3988.  
  3989.  PROCEDURE LMT(secs : LONGCARD; meridiandegree, posdegree : REAL) : LONGINT;
  3990.  
  3991. (*
  3992. ******* Date/LMT ************************************************************
  3993. *
  3994. *   NAME
  3995. *    LMT -- Calculates your local time in your timezone (V33)
  3996. *
  3997. *   SYNOPSIS
  3998. *    secs := LMT(secs,meridian,pos);
  3999. *
  4000. *    PROCEDURE LMT(secs : LONGCARD; meridiandegree,
  4001. *        posdegree : REAL) : LONGINT;
  4002. *
  4003. *   FUNCTION
  4004. *    Calculates your Local Mean Time of you place!
  4005. *
  4006. *   INPUTS
  4007. *    secs     - Seconds of the running day (hours*3600+min*60+sec)
  4008. *    meridian - Degrees of your timezone-meridian
  4009. *    pos      - Degrees of your place
  4010. *
  4011. *   RESULT
  4012. *    secs - Local seconds of the running day
  4013. *
  4014. *   EXAMPLE
  4015. *    ...
  4016. *    secs := LMT(76080,15.0,8.923055556);
  4017. *    ...
  4018. *
  4019. *   NOTES
  4020. *    none
  4021. *
  4022. *   BUGS
  4023. *    No errorcheck, if you put in valid degrees (-180 to +180)
  4024. *
  4025. *   SEE ALSO
  4026. *
  4027. *
  4028. *****************************************************************************
  4029. *
  4030. *
  4031. *)
  4032.  
  4033.  BEGIN
  4034.    RETURN(LONGINT(secs) + LONGINT((meridiandegree / 15.0 - posdegree / 15.0)*3600.0));
  4035.  END LMT;
  4036.  
  4037.  
  4038.  PROCEDURE TimeToSec(hour,min,sec : SHORTCARD) : LONGCARD;
  4039.  
  4040. (*
  4041. ******* Date/TimeToSec ******************************************************
  4042. *
  4043. *   NAME
  4044. *    TimeToSec -- Returns the time in seconds (V33)
  4045. *
  4046. *   SYNOPSIS
  4047. *    secs := TimeToSec(hour,min,sec);
  4048. *
  4049. *    PROCEDURE TimeToSec(hour,min,sec : SHORTCARD) : LONGCARD;
  4050. *
  4051. *   FUNCTION
  4052. *    Gives you back the time in seconds
  4053. *
  4054. *   INPUTS
  4055. *    hour - hours you want (0-23)
  4056. *    min  - minutes you want (0-59)
  4057. *    sec  - seconds you want (0-59)
  4058. *
  4059. *   RESULT
  4060. *    secs - Time in seconds
  4061. *
  4062. *   EXAMPLE
  4063. *    ...
  4064. *    secs := TimeToSec(21,15,00);
  4065. *    ...
  4066. *
  4067. *   NOTES
  4068. *    Don't forget to convert AM/PM time to 24h time!
  4069. *
  4070. *   BUGS
  4071. *    No errorcheck, if you use a valid time
  4072. *
  4073. *   SEE ALSO
  4074. *    SecToTime()
  4075. *
  4076. *****************************************************************************
  4077. *
  4078. *
  4079. *)
  4080.  
  4081.  BEGIN
  4082.    RETURN(LONGCARD(hour)*3600+LONGCARD(min)*60+sec);
  4083.  END TimeToSec;
  4084.  
  4085.  
  4086.  PROCEDURE SecToTime(secs : LONGCARD; VAR hour,min,sec : SHORTCARD);
  4087.  
  4088. (*
  4089. ******* Date/SecToTime ******************************************************
  4090. *
  4091. *   NAME
  4092. *    SecToTime -- Returns the time from seconds (V33)
  4093. *
  4094. *   SYNOPSIS
  4095. *    SecToTime(secs,hour,min,sec);
  4096. *
  4097. *    PROCEDURE SecToTime(secs : LONGCARD; VAR hour,min,sec : SHORTCARD);
  4098. *
  4099. *   FUNCTION
  4100. *    Gives you back the time from the specified seconds
  4101. *
  4102. *   INPUTS
  4103. *    secs - Time in seconds
  4104. *
  4105. *   RESULT
  4106. *    hour - hours (0-23)
  4107. *    min  - minutes (0-59)
  4108. *    sec  - seconds (0-59)
  4109. *
  4110. *   EXAMPLE
  4111. *    ...
  4112. *    SecToTime(76860,hour,min,sec);
  4113. *    ...
  4114. *
  4115. *   NOTES
  4116. *    Don't forget to convert 24h time to AM/PM time if needed!
  4117. *
  4118. *   BUGS
  4119. *    No errorcheck, if you use a valid time
  4120. *
  4121. *   SEE ALSO
  4122. *    TimeToSec()
  4123. *
  4124. *****************************************************************************
  4125. *
  4126. *
  4127. *)
  4128.  
  4129.  BEGIN
  4130.    hour := SHORTCARD(secs DIV 3600);
  4131.    secs := secs - LONGCARD(hour) * 3600;
  4132.    min := SHORTCARD(secs DIV 60);
  4133.    sec := SHORTCARD(secs - min * 60);
  4134.  END SecToTime;
  4135.  
  4136.  (* ----------------------------------------------------------------------- *)
  4137.  
  4138.  PROCEDURE JulianWeek(day,month : SHORTCARD; year : INTEGER) : SHORTCARD;
  4139.  
  4140. (*
  4141. ******* Date/JulianWeek *****************************************************
  4142. *
  4143. *   NAME
  4144. *    JulianWeek -- Gets the weeknumber of a specified date. (V33)
  4145. *
  4146. *   SYNOPSIS
  4147. *    weeknr := JulianWeek(day,month,year);
  4148. *
  4149. *    PROCEDURE JulianWeek(day,month : SHORTCARD;
  4150. *        year : INTEGER) : SHORTCARD;
  4151. *
  4152. *   FUNCTION
  4153. *    JulianWeek gets the weeknumber for a specified date.
  4154. *
  4155. *   INPUTS
  4156. *    day   - day of the date
  4157. *    month - month of the date
  4158. *    year  - year of the date
  4159. *
  4160. *   RESULT
  4161. *    week - This is the number of the week the specified date lies in.
  4162. *        If the first day in a new year is a Friday, Saturday or
  4163. *        Sunday, this would be the last week of the last year!
  4164. *        If the 29.12. is a Monday, the 30.12. is a Monday or a Tuesday,
  4165. *        the 31.12. is a Monday, Tuesday or a Wednesday this is the
  4166. *        first week of the next year!
  4167. *
  4168. *   EXAMPLE
  4169. *    ...
  4170. *    weeknr := JulianWeek(4,10,1582);
  4171. *    ...
  4172. *
  4173. *   NOTES
  4174. *    It is is better only to use this function for years from 0 to 1582!
  4175. *
  4176. *   BUGS
  4177. *    For years < 0 errors could occur.
  4178. *
  4179. *   SEE ALSO
  4180. *    GregorianWeek(),HeisWeek(),JulianWeekday(),JulianDaySmaller(),
  4181. *    JulianDayDiff()
  4182. *
  4183. *****************************************************************************
  4184. *
  4185. *
  4186. *)
  4187.  
  4188.  TYPE
  4189.     Wds    = SET OF Weekdays;
  4190.  
  4191.  VAR
  4192.     days        : LONGINT;
  4193.     firstweekday    : Weekdays;
  4194.  
  4195.  BEGIN
  4196.    firstweekday := JulianWeekday(1,1,year);
  4197.    days := (JulianDayDiff(1,1,year,day,month,year) + LONGINT(firstweekday) -1) DIV 7;
  4198.    IF firstweekday > Thursday THEN
  4199.      IF days = 0 THEN
  4200.        days := JulianWeek(31,12,year-1);
  4201.      ELSIF (firstweekday = Sunday) AND JulianLeapYear(year) AND (month = 12) AND (day = 31) THEN
  4202.        days := 1;
  4203.      END;
  4204.      RETURN(SHORTCARD(days));
  4205.    ELSE
  4206.      IF ~JulianDaySmaller(day,month,year,29,12,year) THEN
  4207.        firstweekday := JulianWeekday(day,12,year);
  4208.        CASE day OF
  4209.          29 : IF firstweekday = Monday THEN
  4210.                 days := 0;
  4211.               END;|
  4212.          30 : IF firstweekday IN Wds{Monday,Tuesday} THEN
  4213.                 days := 0;
  4214.               END;|
  4215.          31 : IF firstweekday IN Wds{Monday,Tuesday,Wednesday} THEN
  4216.                 days := 0;
  4217.               END;
  4218.        ELSE
  4219.        END;
  4220.      END;
  4221.      RETURN(SHORTCARD(days +1));
  4222.    END;
  4223.  END JulianWeek;
  4224.  
  4225.  
  4226.  PROCEDURE GregorianWeek(day,month : SHORTCARD; year : INTEGER) : SHORTCARD;
  4227.  
  4228. (*
  4229. ******* Date/GregorianWeek **************************************************
  4230. *
  4231. *   NAME
  4232. *    GregorianWeek -- Gets the weeknumber of a specified date. (V33)
  4233. *
  4234. *   SYNOPSIS
  4235. *    weeknr := GregorianWeek(day,month,year);
  4236. *
  4237. *    PROCEDURE GregorianWeek(day,month : SHORTCARD;
  4238. *        year : INTEGER) : SHORTCARD;
  4239. *
  4240. *   FUNCTION
  4241. *    GregorianWeek gets the weeknumber for a specified date.
  4242. *
  4243. *   INPUTS
  4244. *    day   - day of the date
  4245. *    month - month of the date
  4246. *    year  - year of the date
  4247. *
  4248. *   RESULT
  4249. *    week - This is the number of the week the specified date lies in.
  4250. *        If the first day in a new year is a Friday, Saturday or
  4251. *        Sunday, this would be the last week of the last year!
  4252. *        If the 29.12. is a Monday, the 30.12. is a Monday or a Tuesday,
  4253. *        the 31.12. is a Monday, Tuesday or a Wednesday this is the
  4254. *        first week of the next year!
  4255. *
  4256. *   EXAMPLE
  4257. *    ...
  4258. *    weeknr := GregorianWeek(4,10,1582);
  4259. *    ...
  4260. *
  4261. *   NOTES
  4262. *    It is is better only to use this function for years from 0 to 3000!
  4263. *
  4264. *   BUGS
  4265. *    For years < 0 errors could occur.
  4266. *
  4267. *   SEE ALSO
  4268. *    JulianWeek(),HeisWeek(),GregorianDaySmaller(),GregorianWeekday(),
  4269. *    GregorianDayDiff()
  4270. *
  4271. *****************************************************************************
  4272. *
  4273. *
  4274. *)
  4275.  
  4276.  TYPE
  4277.     Wds    = SET OF Weekdays;
  4278.  
  4279.  VAR
  4280.     days        : LONGINT;
  4281.     firstweekday    : Weekdays;
  4282.  
  4283.  BEGIN
  4284.    firstweekday := GregorianWeekday(1,1,year);
  4285.    days := (GregorianDayDiff(1,1,year,day,month,year) + LONGINT(firstweekday) -1) DIV 7;
  4286.    IF firstweekday > Thursday THEN
  4287.      IF days = 0 THEN
  4288.        days := GregorianWeek(31,12,year-1);
  4289.      ELSIF (firstweekday = Sunday) AND GregorianLeapYear(year) AND (month = 12) AND (day = 31) THEN
  4290.        days := 1;
  4291.      END;
  4292.      RETURN(SHORTCARD(days));
  4293.    ELSE
  4294.      IF ~GregorianDaySmaller(day,month,year,29,12,year) THEN
  4295.        firstweekday := GregorianWeekday(day,12,year);
  4296.        CASE day OF
  4297.          29 : IF firstweekday = Monday THEN
  4298.                 days := 0;
  4299.               END;|
  4300.          30 : IF firstweekday IN Wds{Monday,Tuesday} THEN
  4301.                 days := 0;
  4302.               END;|
  4303.          31 : IF firstweekday IN Wds{Monday,Tuesday,Wednesday} THEN
  4304.                 days := 0;
  4305.               END;
  4306.        ELSE
  4307.        END;
  4308.      END;
  4309.      RETURN(SHORTCARD(days +1));
  4310.    END;
  4311.  END GregorianWeek;
  4312.  
  4313.  
  4314.  PROCEDURE HeisWeek(day,month : SHORTCARD; year : INTEGER) : SHORTCARD;
  4315.  
  4316. (*
  4317. ******* Date/HeisWeek *******************************************************
  4318. *
  4319. *   NAME
  4320. *    HeisWeek -- Gets the weeknumber of a specified date. (V33)
  4321. *
  4322. *   SYNOPSIS
  4323. *    weeknr := HeisWeek(day,month,year);
  4324. *
  4325. *    PROCEDURE HeisWeek(day,month : SHORTCARD;
  4326. *        year : INTEGER) : SHORTCARD;
  4327. *
  4328. *   FUNCTION
  4329. *    HeisWeek gets the weeknumber for a specified date.
  4330. *
  4331. *   INPUTS
  4332. *    day   - day of the date
  4333. *    month - month of the date
  4334. *    year  - year of the date
  4335. *
  4336. *   RESULT
  4337. *    week - This is the number of the week the specified date lies in.
  4338. *        If the first day in a new year is a Friday, Saturday or
  4339. *        Sunday, this would be the last week of the last year!
  4340. *        If the 29.12. is a Monday, the 30.12. is a Monday or a Tuesday,
  4341. *        the 31.12. is a Monday, Tuesday or a Wednesday this is the
  4342. *        first week of the next year!
  4343. *
  4344. *   EXAMPLE
  4345. *    ...
  4346. *    weeknr := HeisWeek(4,10,1582);
  4347. *    ...
  4348. *
  4349. *   NOTES
  4350. *    It is is better only to use this function for years from 0 to 8000!
  4351. *
  4352. *   BUGS
  4353. *    For years < 0 errors could occur.
  4354. *
  4355. *   SEE ALSO
  4356. *    JulianWeek(),GregorianWeek(),HeisDayDiff(),HeisDaySmaller(),
  4357. *    HeisWeekday()
  4358. *
  4359. *****************************************************************************
  4360. *
  4361. *
  4362. *)
  4363.  
  4364.  TYPE
  4365.     Wds    = SET OF Weekdays;
  4366.  
  4367.  VAR
  4368.     days        : LONGINT;
  4369.     firstweekday    : Weekdays;
  4370.  
  4371.  BEGIN
  4372.    firstweekday := HeisWeekday(1,1,year);
  4373.    days := (HeisDayDiff(1,1,year,day,month,year) + LONGINT(firstweekday) -1) DIV 7;
  4374.    IF firstweekday > Thursday THEN
  4375.      IF days = 0 THEN
  4376.        days := HeisWeek(31,12,year-1);
  4377.      ELSIF (firstweekday = Sunday) AND HeisLeapYear(year) AND (month = 12) AND (day = 31) THEN
  4378.        days := 1;
  4379.      END;
  4380.      RETURN(SHORTCARD(days));
  4381.    ELSE
  4382.      IF ~HeisDaySmaller(day,month,year,29,12,year) THEN
  4383.        firstweekday := HeisWeekday(day,12,year);
  4384.        CASE day OF
  4385.          29 : IF firstweekday = Monday THEN
  4386.                 days := 0;
  4387.               END;|
  4388.          30 : IF firstweekday IN Wds{Monday,Tuesday} THEN
  4389.                 days := 0;
  4390.               END;|
  4391.          31 : IF firstweekday IN Wds{Monday,Tuesday,Wednesday} THEN
  4392.                 days := 0;
  4393.               END;
  4394.        ELSE
  4395.        END;
  4396.      END;
  4397.      RETURN(SHORTCARD(days +1));
  4398.    END;
  4399.  END HeisWeek;
  4400.  
  4401.  (* ----------------------------------------------------------------------- *)
  4402.  
  4403.  BEGIN
  4404.    (* Gregorian reform in Rom *)
  4405.    BeforeGregorianDay := 4;
  4406.    BeforeGregorianMonth := 10;
  4407.    BeforeGregorianYear := 1582;
  4408.    AfterGregorianDay := 15;
  4409.    AfterGregorianMonth := 10;
  4410.    AfterGregorianYear := 1582;
  4411.    StartHeisDay := 1;
  4412.    StartHeisMonth := 1;
  4413.    StartHeisYear := 3200;
  4414.    (* Dates of Gregorian reform in
  4415.       Deutschland, Niederlande, Schweiz, Dänemark:
  4416.         18.02.1700-01.03.1700
  4417.       Großbritannien
  4418.         02.09.1752-14.09.1752
  4419.       Schweden
  4420.         17.02.1753-01.03.1753
  4421.       Rußland
  4422.     ? (oktober Revolution)
  4423.       Griechenland
  4424.         ??.??.1923-??.??.1923 *)
  4425.    (* Bremen/Arbergen = 8° 55' 23" East, 53° 4' 8" North *)
  4426.  END Date.
  4427.